From b33e29c206482ac6776c682c598518653774ccec Mon Sep 17 00:00:00 2001 From: Adrian Damian <Adrian.Damian@nrc-cnrc.gc.ca> Date: Mon, 22 Sep 2014 16:37:45 -0700 Subject: [PATCH] Re-factored and fixed unit test --- .../nrc/cadc/ac/server/GroupPersistence.java | 8 +- .../ca/nrc/cadc/ac/server/PluginFactory.java | 8 +- .../ca/nrc/cadc/ac/server/ldap/LdapDAO.java | 75 +++- .../nrc/cadc/ac/server/ldap/LdapGroupDAO.java | 353 ++++++++---------- .../nrc/cadc/ac/server/ldap/LdapUserDAO.java | 49 ++- .../cadc/ac/server/ldap/LdapGroupDAOTest.java | 63 +++- 6 files changed, 289 insertions(+), 267 deletions(-) diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/GroupPersistence.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/GroupPersistence.java index 3c55bae0..01701154 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/GroupPersistence.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/GroupPersistence.java @@ -68,16 +68,16 @@ */ package ca.nrc.cadc.ac.server; +import java.security.AccessControlException; +import java.security.Principal; +import java.util.Collection; + import ca.nrc.cadc.ac.Group; import ca.nrc.cadc.ac.GroupAlreadyExistsException; import ca.nrc.cadc.ac.GroupNotFoundException; -import ca.nrc.cadc.ac.IdentityType; import ca.nrc.cadc.ac.Role; import ca.nrc.cadc.ac.UserNotFoundException; import ca.nrc.cadc.net.TransientException; -import java.security.AccessControlException; -import java.security.Principal; -import java.util.Collection; public abstract interface GroupPersistence<T extends Principal> { diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/PluginFactory.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/PluginFactory.java index e1ce4ab0..06d92772 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/PluginFactory.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/PluginFactory.java @@ -125,8 +125,8 @@ public class PluginFactory { try { - Class c = Class.forName(cname); - ret = (GroupPersistence) c.newInstance(); + Class<?> c = Class.forName(cname); + ret = (GroupPersistence<T>) c.newInstance(); } catch (Exception ex) { @@ -149,8 +149,8 @@ public class PluginFactory { try { - Class c = Class.forName(cname); - ret = (UserPersistence) c.newInstance(); + Class<?> c = Class.forName(cname); + ret = (UserPersistence<T>) c.newInstance(); } catch (Exception ex) { diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapDAO.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapDAO.java index 4252ee66..11a7f00b 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapDAO.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapDAO.java @@ -68,22 +68,26 @@ */ package ca.nrc.cadc.ac.server.ldap; +import java.security.AccessControlException; +import java.security.AccessController; +import java.security.Principal; +import java.util.Set; + +import javax.security.auth.Subject; +import javax.security.auth.x500.X500Principal; + import ca.nrc.cadc.auth.HttpPrincipal; import ca.nrc.cadc.auth.NumericPrincipal; import ca.nrc.cadc.auth.OpenIdPrincipal; +import ca.nrc.cadc.net.TransientException; + import com.unboundid.ldap.sdk.DN; import com.unboundid.ldap.sdk.LDAPConnection; import com.unboundid.ldap.sdk.LDAPException; +import com.unboundid.ldap.sdk.ResultCode; import com.unboundid.ldap.sdk.SearchResult; import com.unboundid.ldap.sdk.SearchResultEntry; import com.unboundid.ldap.sdk.SearchScope; -import java.security.AccessControlException; -import java.security.AccessController; -import java.security.Principal; -import java.util.List; -import java.util.Set; -import javax.security.auth.Subject; -import javax.security.auth.x500.X500Principal; public abstract class LdapDAO { @@ -116,7 +120,15 @@ public abstract class LdapDAO { conn = new LDAPConnection(config.getServer(), config.getPort()); conn.bind(config.getAdminUserDN(), config.getAdminPasswd()); + } + return conn; + } + + protected DN getSubjectDN() throws LDAPException + { + if (subjDN == null) + { Subject callerSubject = Subject.getSubject(AccessController.getContext()); if (callerSubject == null) @@ -161,7 +173,7 @@ public abstract class LdapDAO } SearchResult searchResult = - conn.search(config.getUsersDN(), SearchScope.ONE, + getConnection().search(config.getUsersDN(), SearchScope.ONE, ldapField, new String[] {"entrydn"}); if (searchResult.getEntryCount() < 1) @@ -173,17 +185,50 @@ public abstract class LdapDAO subjDN = ((SearchResultEntry) searchResult.getSearchEntries() .get(0)).getAttributeValueAsDN("entrydn"); } - - return conn; + return subjDN; } - - protected DN getSubjectDN() throws LDAPException + + /** + * Checks the Ldap result code, and if the result is not SUCCESS, + * throws an appropriate exception. This is the place to decide on + * mapping between ldap errors and exception types + * @param code + * @param errorMsg + * @throws TransientException + */ + protected static void checkLdapResult(ResultCode code, String errorMsg) + throws TransientException { - if (subjDN == null) + String msg = ""; + if (errorMsg != null) { - getConnection(); + msg = "(" + errorMsg + ")"; + } + if (code == ResultCode.INSUFFICIENT_ACCESS_RIGHTS) + { + throw new AccessControlException("Not authorized " + msg); + } + else if (code == ResultCode.INVALID_CREDENTIALS) + { + throw new AccessControlException("Invalid credentials " + msg); + } + else if (code == ResultCode.SUCCESS) + { + // all good. nothing to do + } + else if (code == ResultCode.PARAM_ERROR) + { + throw new IllegalArgumentException("Error in Ldap parameters " + msg); + } + else if (code == ResultCode.BUSY || + code == ResultCode.CONNECT_ERROR ) + { + throw new TransientException("Connection problems " + msg ); + } + else + { + throw new RuntimeException("Ldap error" + msg); } - return subjDN; } } 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 13580e05..1a7b5f85 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 @@ -94,9 +94,11 @@ import com.unboundid.ldap.sdk.DN; import com.unboundid.ldap.sdk.Filter; import com.unboundid.ldap.sdk.LDAPException; import com.unboundid.ldap.sdk.LDAPResult; +import com.unboundid.ldap.sdk.LDAPSearchException; import com.unboundid.ldap.sdk.Modification; import com.unboundid.ldap.sdk.ModificationType; import com.unboundid.ldap.sdk.ModifyRequest; +import com.unboundid.ldap.sdk.ResultCode; import com.unboundid.ldap.sdk.SearchRequest; import com.unboundid.ldap.sdk.SearchResult; import com.unboundid.ldap.sdk.SearchResultEntry; @@ -122,7 +124,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } /** - * Creates the group. + * Persists a group. * * @param group The group to create * @@ -142,6 +144,12 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO throw new IllegalArgumentException("Group owner must be specified"); } + if (!group.getProperties().isEmpty()) + { + throw new UnsupportedOperationException( + "Support for groups properties not available"); + } + if (!isCreatorOwner(group.getOwner())) { throw new AccessControlException("Group owner must be creator"); @@ -149,28 +157,13 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO try { - getGroup(group.getID()); - throw new GroupAlreadyExistsException(group.getID()); - } - catch (GroupNotFoundException ex) - { - try - { - if (!group.getProperties().isEmpty()) - { - throw new UnsupportedOperationException( - "Support for groups properties not available"); - } - - try - { - getInactiveGroup(group); - return reactivateGroup(group); - } - catch (GroupNotFoundException e) - { - // ignore - } + Group newGroup = reactivateGroup(group); + if ( newGroup != null) + { + return newGroup; + } + else + { DN ownerDN = userPersist.getUserDN(group.getOwner()); @@ -180,13 +173,15 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO group.description, group.getUserMembers(), group.getGroupMembers()); + LdapDAO.checkLdapResult(result.getResultCode(), null); // add group to admin groups tree result = addGroup(getAdminGroupDN(group.getID()), group.getID(), ownerDN, group.description, - group.getUserMembers(), - group.getGroupMembers()); + group.getUserAdmins(), + group.getGroupAdmins()); + LdapDAO.checkLdapResult(result.getResultCode(), null); try { @@ -197,19 +192,20 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO throw new RuntimeException("BUG: new group not found"); } } - catch (LDAPException e) - { - e.printStackTrace(); - throw new RuntimeException(e); - } } + catch (LDAPException e) + { + LdapDAO.checkLdapResult(e.getResultCode(), + e.getDiagnosticMessage()); + return null; //TODO + } } 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 + throws UserNotFoundException, LDAPException, TransientException { // add new group List<Attribute> attributes = new ArrayList<Attribute>(); @@ -242,7 +238,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } AddRequest addRequest = new AddRequest(groupDN, attributes); - addRequest.addControl( new ProxiedAuthorizationV2RequestControl( "dn:" + getSubjectDN().toNormalizedString())); @@ -250,91 +245,66 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO return getConnection().add(addRequest); } - private Group getInactiveGroup(final Group group) + + /** + * 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 + * @throws UserNotFoundException + * @throws GroupNotFoundException + * @throws TransientException + * @throws GroupAlreadyExistsException + */ + private Group reactivateGroup(final Group group) throws AccessControlException, UserNotFoundException, - GroupNotFoundException + TransientException, GroupAlreadyExistsException { - Group inactiveGroup; try { - inactiveGroup = getInactiveGroup(getGroupDN(group.getID()) - .toNormalizedString(), group.getID()); + // check group name exists + Filter filter = Filter.createEqualityFilter("cn", group.getID()); - if (inactiveGroup == null) + SearchRequest searchRequest = + new SearchRequest( + getGroupDN(group.getID()) + .toNormalizedString(), SearchScope.SUB, filter, + new String[] {"nsaccountlock"}); + + searchRequest.addControl( + new ProxiedAuthorizationV2RequestControl("dn:" + + getSubjectDN().toNormalizedString())); + + SearchResultEntry searchResult = + getConnection().searchForEntry(searchRequest); + + if (searchResult == null) { return null; } - if (!group.getOwner().equals(inactiveGroup.getOwner())) + if (searchResult.getAttributeValue("nsaccountlock") == null) { - throw new AccessControlException( - "Inactive group not owned be requestor"); + throw new + GroupAlreadyExistsException("Group already exists " + group.getID()); } - - Group inactiveAdminGroup = getInactiveGroup( - getAdminGroupDN(group.getID()).toNormalizedString(), - group.getID()); - - if (inactiveAdminGroup == null) + + // activate group + try { - throw new RuntimeException( - "BUG: adminGroup not found for group " + group.getID()); - } - - if (!group.getOwner().equals(inactiveAdminGroup.getOwner())) + return modifyGroup(group, true); + } + catch (GroupNotFoundException e) { throw new RuntimeException( - "Bug: adminGroup owner doesn't match " - + "group owner for group " + group.getID()); - } - return inactiveGroup; + "BUG: group to modify does not exist" + group.getID()); + } } catch (LDAPException e) { - // TODO Auto-generated catch block - throw new RuntimeException("BUG: LDAP Exception: ", e); + LdapDAO.checkLdapResult(e.getResultCode(), e.getDiagnosticMessage()); } - - - } - - private Group getInactiveGroup(final String groupDN, final String groupID) - throws UserNotFoundException, LDAPException, GroupNotFoundException - { - 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); - throw new GroupNotFoundException(msg); - } - - String groupCN = searchResult.getAttributeValue("cn"); - DN groupOwner = searchResult.getAttributeValueAsDN("owner"); - - User<X500Principal> owner = userPersist.getMember(groupOwner); - - return new Group(groupCN, owner); - } - - private Group reactivateGroup(final Group group) - throws UserNotFoundException, LDAPException, TransientException, AccessControlException, GroupNotFoundException - { - return modifyGroup(group, true); + return null; } @@ -410,18 +380,45 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO new ProxiedAuthorizationV2RequestControl("dn:" + getSubjectDN().toNormalizedString())); - SearchResultEntry searchResult = - getConnection().searchForEntry(searchRequest); + SearchResult searchResult = null; + try + { + searchResult = + getConnection().search(searchRequest); + } + catch (LDAPSearchException e) + { + if (e.getResultCode() == ResultCode.AUTHORIZATION_DENIED) + { + throw new AccessControlException("Unauthorized to access group " + groupID); + } + else if (e.getResultCode() == ResultCode.NO_SUCH_OBJECT) + { + String msg = "Group not found " + groupID; + logger.debug(msg); + throw new GroupNotFoundException(groupID); + } + else + { + throw new RuntimeException("Unknown LDAP exception: " + e.getResultCode()); + } + } - if (searchResult == null) + if (searchResult.getEntryCount() == 0) { + // deleted groups? String msg = "Group not found " + groupID; logger.debug(msg); throw new GroupNotFoundException(groupID); } - String groupCN = searchResult.getAttributeValue("cn"); - DN groupOwner = searchResult.getAttributeValueAsDN("owner"); + if (searchResult.getEntryCount() >1) + { + throw new RuntimeException("BUG: multiple results when retrieving group " + groupID); + } + SearchResultEntry searchEntry = searchResult.getSearchEntries().get(0); + String groupCN = searchEntry.getAttributeValue("cn"); + DN groupOwner = searchEntry.getAttributeValueAsDN("owner"); User<X500Principal> owner; try @@ -434,22 +431,22 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } Group ldapGroup = new Group(groupCN, owner); - if (searchResult.hasAttribute("description")) + if (searchEntry.hasAttribute("description")) { ldapGroup.description = - searchResult.getAttributeValue("description"); + searchEntry.getAttributeValue("description"); } - if (searchResult.hasAttribute("modifytimestamp")) + if (searchEntry.hasAttribute("modifytimestamp")) { ldapGroup.lastModified = - searchResult.getAttributeValueAsDate("modifytimestamp"); + searchEntry.getAttributeValueAsDate("modifytimestamp"); } if (withMembers) { - if (searchResult.getAttributeValues("uniquemember") != null) + if (searchEntry.getAttributeValues("uniquemember") != null) { - for (String member : searchResult + for (String member : searchEntry .getAttributeValues("uniquemember")) { DN memberDN = new DN(member); @@ -485,10 +482,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } catch (LDAPException e1) { - // TODO check which LDAP exceptions are transient and which - // ones are - // access control - throw new TransientException("Error getting the group", e1); + LdapDAO.checkLdapResult(e1.getResultCode(), e1.getDiagnosticMessage()); + throw new GroupNotFoundException("Not found " + groupID); } } @@ -508,6 +503,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO throws GroupNotFoundException, TransientException, AccessControlException, UserNotFoundException { + getGroup(group.getID()); //group must exists first return modifyGroup(group, false); } @@ -521,16 +517,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO throw new UnsupportedOperationException( "Support for groups properties not available"); } - - // check if group exists - if (withActivate) - { - getInactiveGroup(group); - } - else - { - getGroup(group.getID()); - } List<Modification> mods = new ArrayList<Modification>(); List<Modification> adminMods = new ArrayList<Modification>(); @@ -552,16 +538,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO List<String> newMembers = new ArrayList<String>(); for (User<?> member : group.getUserMembers()) { - DN memberDN; - try - { - memberDN = userPersist.getUserDN(member); - } - catch (LDAPException e) - { - throw new UserNotFoundException("User not found " - + member.getUserID()); - } + DN memberDN = userPersist.getUserDN(member); newMembers.add(memberDN.toNormalizedString()); } for (Group gr : group.getGroupMembers()) @@ -572,16 +549,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO List<String> newAdmins = new ArrayList<String>(); for (User<?> member : group.getUserAdmins()) { - DN memberDN; - try - { - memberDN = userPersist.getUserDN(member); - } - catch (LDAPException e) - { - throw new UserNotFoundException( - "User not found " + member.getUserID()); - } + DN memberDN = userPersist.getUserDN(member); newAdmins.add(memberDN.toNormalizedString()); } for (Group gr : group.getGroupAdmins()) @@ -602,24 +570,21 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO modifyRequest.addControl( new ProxiedAuthorizationV2RequestControl( "dn:" + getSubjectDN().toNormalizedString())); - LDAPResult result = getConnection().modify(modifyRequest); - } - catch (LDAPException e1) - { - throw new RuntimeException("LDAP problem", e1); - } - // modify the group itself now - modifyRequest = new ModifyRequest(getGroupDN(group.getID()), mods); - try - { + LdapDAO.checkLdapResult(getConnection(). + modify(modifyRequest).getResultCode(), null); + + // modify the group itself now + modifyRequest = new ModifyRequest(getGroupDN(group.getID()), mods); + modifyRequest.addControl( new ProxiedAuthorizationV2RequestControl( "dn:" + getSubjectDN().toNormalizedString())); - LDAPResult result = getConnection().modify(modifyRequest); + LdapDAO.checkLdapResult(getConnection(). + modify(modifyRequest).getResultCode(), null); } catch (LDAPException e1) { - throw new RuntimeException("LDAP problem", e1); + LdapDAO.checkLdapResult(e1.getResultCode(), e1.getDiagnosticMessage()); } try { @@ -688,10 +653,11 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO new ProxiedAuthorizationV2RequestControl( "dn:" + getSubjectDN().toNormalizedString())); LDAPResult result = getConnection().modify(modifyRequest); + LdapDAO.checkLdapResult(result.getResultCode(), null); } catch (LDAPException e1) { - throw new RuntimeException("LDAP problem", e1); + LdapDAO.checkLdapResult(e1.getResultCode(), e1.getDiagnosticMessage()); } try @@ -723,18 +689,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO GroupNotFoundException, UserNotFoundException { User<T> user = new User<T>(userID); - DN userDN; - try - { - userDN = userPersist.getUserDN(user); - } - catch (LDAPException e) - { - // TODO check which LDAP exceptions are transient and which - // ones are - // access control - throw new TransientException("Error getting user", e); - } + DN userDN = userPersist.getUserDN(user); if (role == Role.OWNER) { @@ -756,6 +711,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO throws TransientException, AccessControlException, GroupNotFoundException, UserNotFoundException { + Collection<Group> groups = new ArrayList<Group>(); try { Filter filter = Filter.createEqualityFilter("owner", @@ -775,7 +731,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO new ProxiedAuthorizationV2RequestControl("dn:" + getSubjectDN().toNormalizedString())); - Collection<Group> groups = new ArrayList<Group>(); SearchResult results = getConnection().search(searchRequest); for (SearchResultEntry result : results.getSearchEntries()) { @@ -791,22 +746,17 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } catch (IllegalArgumentException ignore) { } } - - return groups; } catch (LDAPException e1) { - // TODO check which LDAP exceptions are transient and which - // ones are - // access control - throw new TransientException("Error getting groups", e1); + LdapDAO.checkLdapResult(e1.getResultCode(), e1.getDiagnosticMessage()); } + return groups; } - protected Collection<Group> getMemberGroups(User<T> user, DN userDN, - String groupID) - throws TransientException, AccessControlException, - GroupNotFoundException, UserNotFoundException + protected Collection<Group> getMemberGroups(User<T> user, DN userDN, + String groupID) throws TransientException, AccessControlException, + GroupNotFoundException, UserNotFoundException { if (groupID != null) { @@ -816,38 +766,37 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO groups.add(getGroup(groupID, false)); } return groups; - } + } else { + Collection<Group> groups = 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())); + filters.add(Filter.createEqualityFilter("cn", group.getID())); } Filter filter = Filter.createORFilter(filters); - SearchRequest searchRequest = new SearchRequest( - config.getAdminGroupsDN(), SearchScope.SUB, filter, - "cn"); - + 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()); + LdapDAO.checkLdapResult(e.getResultCode(), + e.getDiagnosticMessage()); } + return groups; } } @@ -856,6 +805,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO throws TransientException, AccessControlException, GroupNotFoundException, UserNotFoundException { + Collection<Group> groups = new ArrayList<Group>(); try { Collection<Group> queryGroups = new ArrayList<Group>(); @@ -898,7 +848,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO // } } - Collection<Group> groups = new ArrayList<Group>(); if (filters.isEmpty()) { return groups; @@ -932,15 +881,13 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } catch (IllegalArgumentException ignore) { } } - return groups; + } catch (LDAPException e) { - // TODO check which LDAP exceptions are transient and which - // ones are - // access control - throw new TransientException("Error getting groups", e); + LdapDAO.checkLdapResult(e.getResultCode(), e.getDiagnosticMessage()); } + return groups; } // protected Collection<Group> getRWGroups2(User<T> user, DN userDN, @@ -1058,7 +1005,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * @param groupID * @return */ - protected DN getGroupDN(final String groupID) + protected DN getGroupDN(final String groupID) throws TransientException { try { @@ -1066,6 +1013,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } catch (LDAPException e) { + LdapDAO.checkLdapResult(e.getResultCode(), e.getDiagnosticMessage()); } throw new IllegalArgumentException(groupID + " not a valid group ID"); } @@ -1075,7 +1023,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * @param groupID * @return */ - protected DN getAdminGroupDN(final String groupID) + protected DN getAdminGroupDN(final String groupID) throws TransientException { try { @@ -1083,6 +1031,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } catch (LDAPException e) { + LdapDAO.checkLdapResult(e.getResultCode(), e.getDiagnosticMessage()); } throw new IllegalArgumentException(groupID + " not a valid group ID"); } diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java index bb11f40a..8c21c14e 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java @@ -84,7 +84,6 @@ import ca.nrc.cadc.ac.PersonalDetails; import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.UserNotFoundException; import ca.nrc.cadc.auth.HttpPrincipal; -import ca.nrc.cadc.auth.NumericPrincipal; import ca.nrc.cadc.net.TransientException; import com.unboundid.ldap.sdk.CompareRequest; @@ -167,7 +166,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO } catch (LDAPException e) { - e.printStackTrace(); + LdapDAO.checkLdapResult(e.getResultCode(), e.getDiagnosticMessage()); } if (searchResult == null) @@ -202,6 +201,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO public Collection<Group> getUserGroups(T userID) throws UserNotFoundException, TransientException, AccessControlException { + Collection<Group> groups = new HashSet<Group>(); try { String searchField = (String) userLdapAttrib.get(userID.getClass()); @@ -227,8 +227,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO SearchResultEntry searchResult = getConnection().searchForEntry(searchRequest); - - Collection<Group> groups = new HashSet<Group>(); + if (searchResult != null) { String[] members = @@ -248,16 +247,13 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO catch (IllegalArgumentException ignore) { } } } - } - return groups; + } } catch (LDAPException e) { - // TODO check which LDAP exceptions are transient and which - // ones are - // access control - throw new TransientException("Error getting user groups", e); + LdapDAO.checkLdapResult(e.getResultCode(), e.getDiagnosticMessage()); } + return groups; } /** @@ -310,11 +306,9 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO } catch (LDAPException e1) { - // TODO check which LDAP exceptions are transient and which - // ones are - // access control - throw new TransientException("Error getting the user", e1); + LdapDAO.checkLdapResult(e1.getResultCode(), e1.getDiagnosticMessage()); } + return false; } public boolean isMember(T userID, String groupID) @@ -347,11 +341,9 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO } catch (LDAPException e) { - // TODO check which LDAP exceptions are transient and which - // ones are - // access control - throw new TransientException("Error getting the user", e); + LdapDAO.checkLdapResult(e.getResultCode(), e.getDiagnosticMessage()); } + return false; } /** @@ -401,7 +393,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO DN getUserDN(User<? extends Principal> user) - throws LDAPException, UserNotFoundException + throws UserNotFoundException, TransientException { String searchField = (String) userLdapAttrib.get(user.getUserID().getClass()); if (searchField == null) @@ -413,17 +405,22 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO searchField = "(" + searchField + "=" + user.getUserID().getName() + ")"; - SearchRequest searchRequest = - new SearchRequest(this.config.getUsersDN(), SearchScope.SUB, - searchField, new String[] {"entrydn"}); + SearchResultEntry searchResult = null; + try + { + SearchRequest searchRequest = new SearchRequest(this.config.getUsersDN(), SearchScope.SUB, + searchField, new String[] {"entrydn"}); -// searchRequest.addControl( -// new ProxiedAuthorizationV2RequestControl("dn:" + -// getSubjectDN().toNormalizedString())); - SearchResultEntry searchResult = + searchResult = getConnection().searchForEntry(searchRequest); + } catch (LDAPException e) + { + LdapDAO.checkLdapResult(e.getResultCode(), e.getDiagnosticMessage()); + } + + if (searchResult == null) { String msg = "User not found " + user.getUserID().toString(); diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java index 922432fb..677a4dad 100644 --- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java +++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java @@ -89,7 +89,8 @@ public class LdapGroupDAOTest static User<X500Principal> unknownUser; static User<X500Principal> adminUser; - static Subject authSubject; + static Subject authSubject1; + static Subject authSubject2; static Subject anonSubject; static LdapConfig config; @@ -110,8 +111,11 @@ public class LdapGroupDAOTest unknownUser = new User<X500Principal>(unknownPrincipal); adminUser = new User<X500Principal>(adminPrincipal); - authSubject = new Subject(); - authSubject.getPrincipals().add(daoTestUser1.getUserID()); + authSubject1 = new Subject(); + authSubject1.getPrincipals().add(daoTestUser1.getUserID()); + + authSubject2 = new Subject(); + authSubject2.getPrincipals().add(daoTestUser2.getUserID()); anonSubject = new Subject(); anonSubject.getPrincipals().add(unknownUser.getUserID()); @@ -134,7 +138,7 @@ public class LdapGroupDAOTest public void testOneGroup() throws Exception { // do everything as owner - Subject.doAs(authSubject, new PrivilegedExceptionAction<Object>() + Subject.doAs(authSubject1, new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { @@ -218,7 +222,7 @@ public class LdapGroupDAOTest public void testSearchOwnerGroups() throws Exception { // do everything as owner - Subject.doAs(authSubject, new PrivilegedExceptionAction<Object>() + Subject.doAs(authSubject1, new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { @@ -263,7 +267,7 @@ public class LdapGroupDAOTest public void testSearchMemberGroups() throws Exception { // do everything as owner - Subject.doAs(authSubject, new PrivilegedExceptionAction<Object>() + Subject.doAs(authSubject1, new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { @@ -310,7 +314,7 @@ public class LdapGroupDAOTest public void testSearchRWGroups() throws Exception { // do everything as owner - Subject.doAs(authSubject, new PrivilegedExceptionAction<Object>() + Subject.doAs(authSubject1, new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { @@ -371,7 +375,7 @@ public class LdapGroupDAOTest } }); - Subject.doAs(authSubject, new PrivilegedExceptionAction<Object>() + Subject.doAs(authSubject1, new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { @@ -405,7 +409,7 @@ public class LdapGroupDAOTest { final String groupID = getGroupID(); - Subject.doAs(authSubject, new PrivilegedExceptionAction<Object>() + Subject.doAs(authSubject1, new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { @@ -437,7 +441,7 @@ public class LdapGroupDAOTest } }); - Subject.doAs(authSubject, new PrivilegedExceptionAction<Object>() + Subject.doAs(authSubject1, new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { @@ -452,7 +456,7 @@ public class LdapGroupDAOTest { final String groupID = getGroupID(); - Subject.doAs(authSubject, new PrivilegedExceptionAction<Object>() + Subject.doAs(authSubject1, new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { @@ -484,7 +488,7 @@ public class LdapGroupDAOTest } }); - Subject.doAs(authSubject, new PrivilegedExceptionAction<Object>() + Subject.doAs(authSubject1, new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { @@ -499,7 +503,7 @@ public class LdapGroupDAOTest { final String groupID = getGroupID(); - Subject.doAs(authSubject, new PrivilegedExceptionAction<Object>() + Subject.doAs(authSubject1, new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { @@ -531,7 +535,7 @@ public class LdapGroupDAOTest } }); - Subject.doAs(authSubject, new PrivilegedExceptionAction<Object>() + Subject.doAs(authSubject1, new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { @@ -546,7 +550,7 @@ public class LdapGroupDAOTest { final String groupID = getGroupID(); - Subject.doAs(authSubject, new PrivilegedExceptionAction<Object>() + Subject.doAs(authSubject1, new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { @@ -589,7 +593,7 @@ public class LdapGroupDAOTest } }); - Subject.doAs(authSubject, new PrivilegedExceptionAction<Object>() + Subject.doAs(authSubject1, new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { @@ -597,6 +601,33 @@ public class LdapGroupDAOTest return null; } }); + + + // change the user + + Subject.doAs(authSubject2, new PrivilegedExceptionAction<Object>() + { + + public Object run() throws Exception + { + + + try + { + Group group = getGroupDAO().getGroup(groupID); + assertTrue(group == null); + + fail("searchGroups with unknown user should throw " + + "GroupNotFoundException"); + } + catch (GroupNotFoundException ignore) + { + + } + + return null; + } + }); } private void assertGroupsEqual(Group gr1, Group gr2) -- GitLab