diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapConfig.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapConfig.java index eadbd82675889f7a1372a238df23935ddf4690ad..9157966d3b1ca264d9575daf7ad5aca5a5889adf 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapConfig.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapConfig.java @@ -86,9 +86,11 @@ public class LdapConfig public static final String LDAP_PASSWD = "passwd"; public static final String LDAP_USERS_DN = "usersDn"; public static final String LDAP_GROUPS_DN = "groupsDn"; + public static final String LDAP_ADMIN_GROUPS_DN = "adminGroupsDn"; private String usersDN; private String groupsDN; + private String adminGroupsDN; private String server; private int port; private String adminUserDN; @@ -156,18 +158,26 @@ public class LdapConfig throw new RuntimeException("failed to read property " + LDAP_GROUPS_DN); } + + String ldapAdminGroupsDn = config.getProperty(LDAP_ADMIN_GROUPS_DN); + if (!StringUtil.hasText(ldapAdminGroupsDn)) + { + throw new RuntimeException("failed to read property " + + LDAP_ADMIN_GROUPS_DN); + } return new LdapConfig(server, Integer.valueOf(port), ldapAdmin, - ldapPasswd, ldapUsersDn, ldapGroupsDn); + ldapPasswd, ldapUsersDn, ldapGroupsDn, + ldapAdminGroupsDn); } public LdapConfig(String server, int port, String adminUserDN, - String adminPasswd, String usersDN, String groupsDN) + String adminPasswd, String usersDN, String groupsDN, + String adminGroupsDN) { if (!StringUtil.hasText(server)) { - throw new IllegalArgumentException("Illegal LDAP server name: " + - server); + throw new IllegalArgumentException("Illegal LDAP server name"); } if (port < 0) { @@ -176,23 +186,23 @@ public class LdapConfig } if (!StringUtil.hasText(adminUserDN)) { - throw new IllegalArgumentException("Illegal Admin DN: " + - adminUserDN); + throw new IllegalArgumentException("Illegal Admin DN"); } if (!StringUtil.hasText(adminPasswd)) { - throw new IllegalArgumentException("Illegal Admin password: " + - adminPasswd); + throw new IllegalArgumentException("Illegal Admin password"); } if (!StringUtil.hasText(usersDN)) { - throw new IllegalArgumentException("Illegal users LDAP DN: " + - usersDN); + throw new IllegalArgumentException("Illegal users LDAP DN"); } if (!StringUtil.hasText(groupsDN)) { - throw new IllegalArgumentException("Illegal groups LDAP DN: " + - groupsDN); + throw new IllegalArgumentException("Illegal groups LDAP DN"); + } + if (!StringUtil.hasText(adminGroupsDN)) + { + throw new IllegalArgumentException("Illegal admin groups LDAP DN"); } this.server = server; @@ -201,6 +211,7 @@ public class LdapConfig this.adminPasswd = adminPasswd; this.usersDN = usersDN; this.groupsDN = groupsDN; + this.adminGroupsDN = adminGroupsDN; } public String getUsersDN() @@ -212,6 +223,11 @@ public class LdapConfig { return this.groupsDN; } + + public String getAdminGroupsDN() + { + return this.adminGroupsDN; + } public String getServer() { 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 edd396bb76c551e1d976aba97130abe2bb7d17de..31eff4b1c1476d772ee21375a290faecf8f15fb0 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 @@ -151,22 +151,11 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO throw new IllegalArgumentException("Group owner must be specified"); } - try - { - User<X500Principal> subjectUser = - userPersist.getMember(getSubjectDN()); - if (!subjectUser.equals(group.getOwner())) - { - throw new AccessControlException("Group owner must be group " + - " creator"); - } - } - catch (LDAPException e) + if (!isCreatorOwner(group.getOwner())) { - e.printStackTrace(); - throw new RuntimeException(e); + throw new AccessControlException("Group owner must be creator"); } - + try { getGroup(group.getID()); @@ -175,127 +164,29 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO catch (GroupNotFoundException ex) { try - { - try - { - Group inactiveGroup = getInactiveGroup(group.getID()); - - // Check requestor owns the group. - DN ownerDN = userPersist.getUserDN(group.getOwner()); - if (!ownerDN.equals(getSubjectDN())) - { - throw new AccessControlException( - "Unable to activate group " + group.getID() + - " because " + getSubjectDN().toString() - + " is not the owner"); - } - - List<Modification> mods = new ArrayList<Modification>(); - Modification mod = - new Modification(ModificationType.DELETE, - "nsaccountlock"); - mods.add(mod); - - Group modifiedGroup = modifyGroup(group, inactiveGroup, - mods); - Group activatedGroup = - new ActivatedGroup(modifiedGroup.getID(), - modifiedGroup.getOwner()); - activatedGroup.description = modifiedGroup.description; - activatedGroup.groupRead = modifiedGroup.groupRead; - activatedGroup.groupWrite = modifiedGroup.groupWrite; - activatedGroup.getProperties() - .addAll(modifiedGroup.getProperties()); - activatedGroup.getGroupMembers() - .addAll(modifiedGroup.getGroupMembers()); - activatedGroup.getUserMembers() - .addAll(modifiedGroup.getUserMembers()); - return activatedGroup; - } - catch (GroupNotFoundException ignore) {} - + { if (!group.getProperties().isEmpty()) { throw new UnsupportedOperationException( "Support for groups properties not available"); } - - DN ownerDN = userPersist.getUserDN(group.getOwner()); - String groupWriteAci = null; - String groupReadAci = null; - if (group.groupWrite != null) - { - DN groupWrite = getGroupDN(group.groupWrite.getID()); - groupWriteAci = GROUP_WRITE_ACI.replace( - ACTUAL_GROUP_TOKEN, - groupWrite.toNormalizedString()); - } - - if (group.groupRead != null) - { - DN groupRead = getGroupDN(group.groupRead.getID()); - groupReadAci = GROUP_READ_ACI.replace( - ACTUAL_GROUP_TOKEN, - groupRead.toNormalizedString()); - } - - // add new group - List<Attribute> attributes = new ArrayList<Attribute>(); - attributes.add(new Attribute("objectClass", - "groupofuniquenames")); - - attributes.add(new Attribute("cn", group.getID())); - if (group.description != null) - { - attributes.add(new Attribute("description", - group.description)); - } - - attributes.add(new Attribute("owner", - ownerDN.toNormalizedString())); - - // acis - List<String> acis = new ArrayList<String>(); - if (groupWriteAci != null) - { - acis.add(groupWriteAci); - } - if (groupReadAci != null) - { - acis.add(groupReadAci); - } - - if (!acis.isEmpty()) - { - attributes.add(new Attribute("aci", - (String[]) acis.toArray(new String[acis.size()]))); - } - - 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()) + + Group inactiveGroup = getInactiveGroup(group.getID()); + if (inactiveGroup != null) { - attributes.add(new Attribute("uniquemember", - (String[]) members.toArray(new String[members.size()]))); + return reactiveGroup(group, inactiveGroup); } - - AddRequest addRequest = - new AddRequest(getGroupDN(group.getID()), attributes); - - addRequest.addControl( - new ProxiedAuthorizationV2RequestControl( - "dn:" + getSubjectDN().toNormalizedString())); - - LDAPResult result = getConnection().add(addRequest); + + DN ownerDN = userPersist.getUserDN(group.getOwner()); + Attribute ownerAttribute = + new Attribute("owner", ownerDN.toNormalizedString()); + + // add group to groups tree + LDAPResult result = addGroup(group, ownerAttribute); + + // add group to admin groups tree + result = addAdminGroup(group, ownerAttribute); + try { return getGroup(group.getID()); @@ -412,36 +303,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } } } - - // TODO not sure this is going to fly... - if (group.getAttributeValues("aci") != null) - { - for (String aci : group.getAttributeValues("aci")) - { - if (aci.contains("Group Read")) - { - // TODO it's gotta be a better way to do this. - String grRead = aci.substring( - aci.indexOf("ldap:///")); - grRead = grRead.substring(grRead.indexOf("cn=") + 3, - grRead.indexOf(',')); - - Group groupRead = new Group(grRead.trim()); - ldapGroup.groupRead = groupRead; - } - else if (aci.contains("Group Write")) - { - // TODO it's gotta be a better way to do this. - String grWrite = aci.substring( - aci.indexOf("ldap:///")); - grWrite = grWrite.substring(grWrite.indexOf("cn=") + 3, - grWrite.indexOf(',')); - - Group groupWrite = getGroup(grWrite.trim()); - ldapGroup.groupWrite = groupWrite; - } - } - } } return ldapGroup; @@ -510,36 +371,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO newGroup.description)); } - List<String> acis = new ArrayList<String>(); - if (newGroup.groupRead != null) - { - if (newGroup.groupRead.equals(newGroup)) - { - throw new IllegalArgumentException( - "cyclical reference from groupRead to group"); - } - - DN readGrDN = getGroupDN(newGroup.groupRead.getID()); - acis.add(GROUP_READ_ACI.replace(ACTUAL_GROUP_TOKEN, - readGrDN.toNormalizedString())); - } - - if (newGroup.groupWrite != null) - { - if (newGroup.groupWrite.equals(newGroup)) - { - throw new IllegalArgumentException( - "cyclical reference from groupWrite to group"); - } - - DN writeGrDN = getGroupDN(newGroup.groupWrite.getID()); - acis.add(GROUP_WRITE_ACI.replace(ACTUAL_GROUP_TOKEN, - writeGrDN.toNormalizedString())); - } - - modifs.add(new Modification(ModificationType.REPLACE, "aci", (String[]) - acis.toArray(new String[acis.size()]))); - List<String> newMembers = new ArrayList<String>(); for (User<?> member : newGroup.getUserMembers()) { @@ -648,12 +479,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO modifs.add(new Modification(ModificationType.DELETE, "description")); } - if (group.groupRead != null || - group.groupWrite != null) - { - modifs.add(new Modification(ModificationType.DELETE, "aci")); - } - if (!group.getGroupMembers().isEmpty() || !group.getUserMembers().isEmpty()) { @@ -829,25 +654,25 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO List<Filter> filters = new ArrayList<Filter>(); for (Group member : queryGroups) { - // Require both groupRead and groupWrite - if (member.groupRead != null && member.groupWrite != null) - { - DN groupRead = getGroupDN(member.groupRead.getID()); - String groupReadAci = - GROUP_READ_ACI.replace(ACTUAL_GROUP_TOKEN, - groupRead.toNormalizedString()); - DN groupWrite = getGroupDN(member.groupRead.getID()); - String groupWriteAci = - GROUP_WRITE_ACI.replace(ACTUAL_GROUP_TOKEN, - groupWrite.toNormalizedString()); - System.out.println(groupReadAci); - System.out.println(groupWriteAci); - - Filter filter = Filter.createANDFilter( - Filter.createEqualityFilter("aci", groupReadAci), - Filter.createEqualityFilter("aci", groupWriteAci)); - filters.add(filter); - } +// // Require both groupRead and groupWrite +// if (member.groupRead != null && member.groupWrite != null) +// { +// DN groupRead = getGroupDN(member.groupRead.getID()); +// String groupReadAci = +// GROUP_READ_ACI.replace(ACTUAL_GROUP_TOKEN, +// groupRead.toNormalizedString()); +// DN groupWrite = getGroupDN(member.groupRead.getID()); +// String groupWriteAci = +// GROUP_WRITE_ACI.replace(ACTUAL_GROUP_TOKEN, +// groupWrite.toNormalizedString()); +// System.out.println(groupReadAci); +// System.out.println(groupWriteAci); +// +// Filter filter = Filter.createANDFilter( +// Filter.createEqualityFilter("aci", groupReadAci), +// Filter.createEqualityFilter("aci", groupWriteAci)); +// filters.add(filter); +// } } Collection<Group> groups = new ArrayList<Group>(); @@ -895,89 +720,89 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } } - protected Collection<Group> getRWGroups2(User<T> user, DN userDN, - String groupID) - throws TransientException, AccessControlException, - GroupNotFoundException, UserNotFoundException - { - try - { - Collection<Group> groups = new ArrayList<Group>(); - - Collection<Group> queryGroups = new ArrayList<Group>(); - if (groupID != null) - { - queryGroups.add(new Group(groupID, user)); - } - else - { - // List of Groups the user belongs to. - queryGroups.addAll(getMemberGroups(user, userDN, groupID)); - - // List of Groups the user owns; - queryGroups.addAll(getOwnerGroups(user, userDN, groupID)); - } - - for (Group member : queryGroups) - { - // Require both groupRead and groupWrite - if (member.groupRead != null && member.groupWrite != null) - { - DN groupRead = getGroupDN(member.groupRead.getID()); - String groupReadAci = - GROUP_READ_ACI.replace(ACTUAL_GROUP_TOKEN, - groupRead.toNormalizedString()); - DN groupWrite = getGroupDN(member.groupWrite.getID()); - String groupWriteAci = - GROUP_WRITE_ACI.replace(ACTUAL_GROUP_TOKEN, - groupWrite.toNormalizedString()); - - Filter filter = Filter.createANDFilter( - Filter.createEqualityFilter("aci", groupReadAci), - Filter.createEqualityFilter("aci", groupWriteAci)); - - SearchRequest searchRequest = new SearchRequest( - config.getGroupsDN(), SearchScope.SUB, filter, - new String[] {"cn", "owner", "description", - "modifytimestamp"}); - - searchRequest.addControl( - new ProxiedAuthorizationV2RequestControl("dn:" + - getSubjectDN().toNormalizedString())); - - SearchResult results = getConnection().search(searchRequest); - for (SearchResultEntry result : results.getSearchEntries()) - { - String groupName = result.getAttributeValue("cn"); - DN ownerDN = result.getAttributeValueAsDN("owner"); - User<X500Principal> owner = userPersist.getMember(ownerDN); - - // Ignore existing illegal group names. - try - { - Group group = new Group(groupName, owner); - group.description = result.getAttributeValue("description"); - group.lastModified = - result.getAttributeValueAsDate("modifytimestamp"); - groups.add(group); - } - 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); - } - } +// protected Collection<Group> getRWGroups2(User<T> user, DN userDN, +// String groupID) +// throws TransientException, AccessControlException, +// GroupNotFoundException, UserNotFoundException +// { +// try +// { +// Collection<Group> groups = new ArrayList<Group>(); +// +// Collection<Group> queryGroups = new ArrayList<Group>(); +// if (groupID != null) +// { +// queryGroups.add(new Group(groupID, user)); +// } +// else +// { +// // List of Groups the user belongs to. +// queryGroups.addAll(getMemberGroups(user, userDN, groupID)); +// +// // List of Groups the user owns; +// queryGroups.addAll(getOwnerGroups(user, userDN, groupID)); +// } +// +// for (Group member : queryGroups) +// { +// // Require both groupRead and groupWrite +// if (member.groupRead != null && member.groupWrite != null) +// { +// DN groupRead = getGroupDN(member.groupRead.getID()); +// String groupReadAci = +// GROUP_READ_ACI.replace(ACTUAL_GROUP_TOKEN, +// groupRead.toNormalizedString()); +// DN groupWrite = getGroupDN(member.groupWrite.getID()); +// String groupWriteAci = +// GROUP_WRITE_ACI.replace(ACTUAL_GROUP_TOKEN, +// groupWrite.toNormalizedString()); +// +// Filter filter = Filter.createANDFilter( +// Filter.createEqualityFilter("aci", groupReadAci), +// Filter.createEqualityFilter("aci", groupWriteAci)); +// +// SearchRequest searchRequest = new SearchRequest( +// config.getGroupsDN(), SearchScope.SUB, filter, +// new String[] {"cn", "owner", "description", +// "modifytimestamp"}); +// +// searchRequest.addControl( +// new ProxiedAuthorizationV2RequestControl("dn:" + +// getSubjectDN().toNormalizedString())); +// +// SearchResult results = getConnection().search(searchRequest); +// for (SearchResultEntry result : results.getSearchEntries()) +// { +// String groupName = result.getAttributeValue("cn"); +// DN ownerDN = result.getAttributeValueAsDN("owner"); +// User<X500Principal> owner = userPersist.getMember(ownerDN); +// +// // Ignore existing illegal group names. +// try +// { +// Group group = new Group(groupName, owner); +// group.description = result.getAttributeValue("description"); +// group.lastModified = +// result.getAttributeValueAsDate("modifytimestamp"); +// groups.add(group); +// } +// 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); +// } +// } - private Group getInactiveGroup(String groupID) - throws UserNotFoundException, GroupNotFoundException, LDAPException + protected Group getInactiveGroup(final String groupID) + throws UserNotFoundException, LDAPException { Filter filter = Filter.createANDFilter( Filter.createEqualityFilter("cn", groupID), @@ -998,7 +823,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { String msg = "Inactive Group not found " + groupID; logger.debug(msg); - throw new GroupNotFoundException(msg); + return null; } String groupCN = searchResult.getAttributeValue("cn"); @@ -1008,6 +833,134 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO 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())); + attributes.add(new Attribute("memberRead", + String.valueOf(group.memberRead))); + + 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 @@ -1038,7 +991,12 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO return group; } - protected DN getGroupDN(String groupID) + /** + * + * @param groupID + * @return + */ + protected DN getGroupDN(final String groupID) { try { @@ -1049,5 +1007,47 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } throw new IllegalArgumentException(groupID + " not a valid group ID"); } + + /** + * + * @param groupID + * @return + */ + protected DN getAdminGroupDN(final String groupID) + { + try + { + return new DN("cn=" + groupID + "," + config.getAdminGroupsDN()); + } + catch (LDAPException e) + { + } + throw new IllegalArgumentException(groupID + " not a valid group ID"); + } + + /** + * + * @param owner + * @return + * @throws UserNotFoundException + */ + protected boolean isCreatorOwner(final User<? extends Principal> owner) + throws UserNotFoundException + { + try + { + User<X500Principal> subjectUser = + userPersist.getMember(getSubjectDN()); + if (subjectUser.equals(owner)) + { + return true; + } + return false; + } + catch (LDAPException e) + { + throw new RuntimeException(e); + } + } } diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapDAOTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapDAOTest.java index 9a2c2caddd06d278b8fd4ff6e13e7047e55019a0..a79aa1a456ba2e629c331b1143f5d08900dec9ea 100644 --- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapDAOTest.java +++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapDAOTest.java @@ -89,10 +89,11 @@ public class LdapDAOTest static int port = 389; static String adminDN = "uid=webproxy,ou=WebProxy,ou=topologymanagement,o=netscaperoot"; static String adminPW = "go4it"; - static String userBaseDN = "ou=Users,ou=ds,dc=canfartest,dc=net"; - static String groupBaseDN = "ou=Groups,ou=ds,dc=canfartest,dc=net"; + static String usersDN = "ou=Users,ou=ds,dc=canfartest,dc=net"; + static String groupsDN = "ou=Groups,ou=ds,dc=canfartest,dc=net"; + static String adminGroupsDN = "ou=adminGroups,ou=ds,dc=canfartest,dc=net"; - LdapConfig config = new LdapConfig(server, port, adminDN, adminPW, userBaseDN, groupBaseDN); + LdapConfig config = new LdapConfig(server, port, adminDN, adminPW, usersDN, groupsDN, adminGroupsDN); @Test public void testLdapBindConnection() throws Exception 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 94081f73add469471820754ac17ba6c20d5e452d..1039a5d3205faef3b04b7b9668e058f5696b1c63 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 @@ -69,10 +69,11 @@ public class LdapGroupDAOTest static int port = 389; static String adminDN = "uid=webproxy,ou=webproxy,ou=topologymanagement,o=netscaperoot"; static String adminPW = "go4it"; - static String userBaseDN = "ou=Users,ou=ds,dc=canfartest,dc=net"; - static String groupBaseDN = "ou=Groups,ou=ds,dc=canfartest,dc=net"; - //static String userBaseDN = "ou=Users,ou=ds,dc=canfar,dc=net"; - //static String groupBaseDN = "ou=Groups,ou=ds,dc=canfar,dc=net"; + static String usersDN = "ou=Users,ou=ds,dc=canfartest,dc=net"; + static String groupsDN = "ou=Groups,ou=ds,dc=canfartest,dc=net"; + static String adminGroupsDN = "ou=adminGroups,ou=ds,dc=canfartest,dc=net"; + //static String usersDN = "ou=Users,ou=ds,dc=canfar,dc=net"; + //static String groupsDN = "ou=Groups,ou=ds,dc=canfar,dc=net"; static String daoTestDN1 = "cn=cadcdaotest1,ou=cadc,o=hia,c=ca"; static String daoTestDN2 = "cn=cadcdaotest2,ou=cadc,o=hia,c=ca"; @@ -115,7 +116,7 @@ public class LdapGroupDAOTest anonSubject = new Subject(); anonSubject.getPrincipals().add(unknownUser.getUserID()); - config = new LdapConfig(server, port, adminDN, adminPW, userBaseDN, groupBaseDN); + config = new LdapConfig(server, port, adminDN, adminPW, usersDN, groupsDN, adminGroupsDN); } LdapGroupDAO<X500Principal> getGroupDAO() @@ -158,24 +159,6 @@ public class LdapGroupDAOTest actualGroup = getGroupDAO().modifyGroup(expectGroup); assertGroupsEqual(expectGroup, actualGroup); - // groupRead - expectGroup.groupRead = otherGroup; - actualGroup = getGroupDAO().modifyGroup(expectGroup); - assertGroupsEqual(expectGroup, actualGroup); - - expectGroup.groupRead = null; - actualGroup = getGroupDAO().modifyGroup(expectGroup); - assertGroupsEqual(expectGroup, actualGroup); - - // groupWrite - expectGroup.groupWrite = otherGroup; - actualGroup = getGroupDAO().modifyGroup(expectGroup); - assertGroupsEqual(expectGroup, actualGroup); - - expectGroup.groupWrite = null; - actualGroup = getGroupDAO().modifyGroup(expectGroup); - assertGroupsEqual(expectGroup, actualGroup); - // userMembers expectGroup.getUserMembers().add(daoTestUser2); actualGroup = getGroupDAO().modifyGroup(expectGroup); @@ -196,8 +179,6 @@ public class LdapGroupDAOTest // delete the group expectGroup.description = "Happy testing"; - expectGroup.groupRead = otherGroup; - expectGroup.groupWrite = otherGroup; expectGroup.getUserMembers().add(daoTestUser2); expectGroup.getGroupMembers().add(otherGroup); @@ -398,9 +379,9 @@ public class LdapGroupDAOTest { getGroupDAO().addGroup(new Group("foo", unknownUser)); fail("addGroup with unknown user should throw " + - "UserNotFoundException"); + "AccessControlException"); } - catch (UserNotFoundException ignore) {} + catch (AccessControlException ignore) {} Group group = getGroupDAO().addGroup(new Group(getGroupID(), daoTestUser1)); @@ -651,9 +632,6 @@ public class LdapGroupDAOTest { assertTrue(gr2.getUserMembers().contains(user)); } - assertEquals(gr1.groupRead, gr2.groupRead); - assertEquals(gr1.groupWrite, gr2.groupWrite); - assertEquals(gr1.groupWrite, gr2.groupWrite); assertEquals(gr1.getProperties(), gr2.getProperties()); for (GroupProperty prop : gr1.getProperties()) { diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAOTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAOTest.java index a742fe5b6d586fa00596cc5df4939262c9b54188..2825cdc67eb244bc2d8ca669cb4e253ab7ef2c6e 100644 --- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAOTest.java +++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAOTest.java @@ -96,8 +96,9 @@ public class LdapUserDAOTest static int port = 389; static String adminDN = "uid=webproxy,ou=Webproxy,ou=topologymanagement,o=netscaperoot"; static String adminPW = "go4it"; - static String userBaseDN = "ou=Users,ou=ds,dc=canfartest,dc=net"; - static String groupBaseDN = "ou=Groups,ou=ds,dc=canfartest,dc=net"; + static String usersDN = "ou=Users,ou=ds,dc=canfartest,dc=net"; + static String groupsDN = "ou=Groups,ou=ds,dc=canfartest,dc=net"; + static String adminGroupsDN = "ou=adminGroups,ou=ds,dc=canfartest,dc=net"; // static String userBaseDN = "ou=Users,ou=ds,dc=canfar,dc=net"; // static String groupBaseDN = "ou=Groups,ou=ds,dc=canfar,dc=net"; @@ -114,7 +115,7 @@ public class LdapUserDAOTest testUser = new User<X500Principal>(new X500Principal(testUserDN)); - config = new LdapConfig(server, port, adminDN, adminPW, userBaseDN, groupBaseDN); + config = new LdapConfig(server, port, adminDN, adminPW, usersDN, groupsDN, adminGroupsDN); } LdapUserDAO<X500Principal> getUserDAO() diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/Group.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/Group.java index 5172ddb934629adcc018d4cdccc02dbed47e9912..c8e8048ee08a45712e47a93380c8441dd42f650a 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/Group.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/Group.java @@ -88,21 +88,14 @@ public class Group // group's group members private Set<Group> groupMembers = new HashSet<Group>(); - public String description; - public Date lastModified; + // group's user admins + private Set<User<? extends Principal>> userAdmins = new HashSet<User<? extends Principal>>(); - // Access Control properties - /** - * group that can read details of this group - * Note: this class does not enforce any access control rules - */ - public Group groupRead; + // group's group admins + private Set<Group> groupAdmins = new HashSet<Group>(); - /** - * group that can read and write details of this group - * Note: this class does not enforce any access control rules - */ - public Group groupWrite; + public String description; + public Date lastModified; /** * Ctor. @@ -186,6 +179,24 @@ public class Group { return groupMembers; } + + /** + * + * @return individual user admins of this group + */ + public Set<User<? extends Principal>> getUserAdmins() + { + return userAdmins; + } + + /** + * + * @return group admins of this group + */ + public Set<Group> getGroupAdmins() + { + return groupAdmins; + } /* (non-Javadoc) * @see java.lang.Object#hashCode() diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/GroupReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/GroupReader.java index 4b666bf54f3cb023faaac7ae1f26f630465d8bf0..8061f48773eeb3913a4b8020aba06af37e703fed 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/GroupReader.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/GroupReader.java @@ -263,38 +263,37 @@ public class GroupReader } - // groupRead - Element groupReadElement = groupElement.getChild("groupRead"); - if (groupReadElement != null) + // userMembers + Element userMembersElement = groupElement.getChild("userMembers"); + if (userMembersElement != null) { - Element groupReadGroupElement = groupReadElement.getChild("group"); - if (groupReadGroupElement != null) + List<Element> userElements = userMembersElement.getChildren("user"); + for (Element userMember : userElements) { - group.groupRead = parseGroup(groupReadGroupElement); + group.getUserMembers().add(UserReader.parseUser(userMember)); } - } - - // groupWrite - Element groupWriteElement = groupElement.getChild("groupWrite"); - if (groupWriteElement != null) + + // groupAdmins + Element groupAdminsElement = groupElement.getChild("groupAdmins"); + if (groupAdminsElement != null) { - Element groupWriteGroupElement = groupWriteElement.getChild("group"); - if (groupWriteGroupElement != null) + List<Element> groupElements = groupAdminsElement.getChildren("group"); + for (Element groupMember : groupElements) { - group.groupWrite = parseGroup(groupWriteGroupElement); + group.getGroupAdmins().add(parseGroup(groupMember)); } } - // userMembers - Element userMembersElement = groupElement.getChild("userMembers"); - if (userMembersElement != null) + // userAdmins + Element userAdminsElement = groupElement.getChild("userAdmins"); + if (userAdminsElement != null) { - List<Element> userElements = userMembersElement.getChildren("user"); + List<Element> userElements = userAdminsElement.getChildren("user"); for (Element userMember : userElements) { - group.getUserMembers().add(UserReader.parseUser(userMember)); + group.getUserAdmins().add(UserReader.parseUser(userMember)); } } diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/GroupWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/GroupWriter.java index 3c4e54471dd9e156be95c2c8aa7b24fa09c4a1bc..93fcd13c61f9a5492beb3468049997cbeb908b25 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/GroupWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/GroupWriter.java @@ -213,22 +213,6 @@ public class GroupWriter groupElement.addContent(groupMembersElement); } - // Group groupRead. - if (group.groupRead != null) - { - Element groupReadElement = new Element("groupRead"); - groupReadElement.addContent(getGroupElement(group.groupRead, false)); - groupElement.addContent(groupReadElement); - } - - // Group groupWrite. - if (group.groupWrite != null) - { - Element groupWriteElement = new Element("groupWrite"); - groupWriteElement.addContent(getGroupElement(group.groupWrite, false)); - groupElement.addContent(groupWriteElement); - } - // Group userMembers if ((group.getUserMembers() != null) && (!group.getUserMembers().isEmpty())) { @@ -239,6 +223,28 @@ public class GroupWriter } groupElement.addContent(userMembersElement); } + + // Group groupAdmins. + if ((group.getGroupAdmins() != null) && (!group.getGroupAdmins().isEmpty())) + { + Element groupAdminsElement = new Element("groupAdmins"); + for (Group groupMember : group.getGroupAdmins()) + { + groupAdminsElement.addContent(getGroupElement(groupMember, false)); + } + groupElement.addContent(groupAdminsElement); + } + + // Group userAdmins + if ((group.getUserAdmins() != null) && (!group.getUserAdmins().isEmpty())) + { + Element userAdminsElement = new Element("userAdmins"); + for (User<? extends Principal> userMember : group.getUserAdmins()) + { + userAdminsElement.addContent(UserWriter.getUserElement(userMember)); + } + groupElement.addContent(userAdminsElement); + } } return groupElement; diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/GroupReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/GroupReaderWriterTest.java index 83675c64da17bab6cdc482c4da213357340d82da..c54f6ee56d0787551e5c3fb7c45a1fad85b67523 100644 --- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/GroupReaderWriterTest.java +++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/GroupReaderWriterTest.java @@ -85,8 +85,8 @@ import org.apache.log4j.Logger; import org.junit.Test; import ca.nrc.cadc.auth.HttpPrincipal; -import ca.nrc.cadc.auth.NumericPrincipal; import ca.nrc.cadc.auth.OpenIdPrincipal; +import static org.junit.Assert.assertTrue; /** * @@ -161,15 +161,15 @@ public class GroupReaderWriterTest expected.lastModified = new Date(); expected.properties.add(new GroupProperty("key", "value", true)); - Group readGroup = new Group("read", new User<Principal>(new X500Principal("cn=foo,o=ca"))); - Group writeGroup = new Group("write", new User<Principal>(new NumericPrincipal(123l))); Group groupMember = new Group("member", new User<Principal>(new OpenIdPrincipal("bar"))); User<Principal> userMember = new User<Principal>(new HttpPrincipal("baz")); + Group groupAdmin = new Group("admin", new User<Principal>(new X500Principal("cn=foo,o=ca"))); + User<Principal> userAdmin = new User<Principal>(new HttpPrincipal("admin")); - expected.groupRead = readGroup; - expected.groupWrite = writeGroup; expected.getGroupMembers().add(groupMember); expected.getUserMembers().add(userMember); + expected.getGroupAdmins().add(groupAdmin); + expected.getUserAdmins().add(userAdmin); StringBuilder xml = new StringBuilder(); GroupWriter.write(expected, xml); @@ -181,8 +181,6 @@ public class GroupReaderWriterTest assertEquals(expected.description, actual.description); assertEquals(expected.lastModified, actual.lastModified); assertEquals(expected.getProperties(), actual.getProperties()); - assertEquals(expected.groupRead, actual.groupRead); - assertEquals(expected.groupWrite, actual.groupWrite); assertEquals(expected.getGroupMembers(), actual.getGroupMembers()); assertEquals(expected.getUserMembers(), actual.getUserMembers()); } diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/GroupTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/GroupTest.java index af09cf893e6144d347dac2eed526d9496ecf1361..6451d53418baf3c5fa1099b97b738c508f27b70b 100644 --- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/GroupTest.java +++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/GroupTest.java @@ -115,17 +115,15 @@ public class GroupTest assertEquals(group3.hashCode(), group4.hashCode()); assertEquals(group3,group4); - group3.description = "Test group"; + group4.getUserAdmins().add(user); assertEquals(group3.hashCode(), group4.hashCode()); assertEquals(group3,group4); - // group read and write equality tests - group3.groupRead = group4; + group3.getGroupAdmins().add(group4); assertEquals(group3.hashCode(), group4.hashCode()); assertEquals(group3,group4); - // group write equality tests - group3.groupWrite = group4; + group3.description = "Test group"; assertEquals(group3.hashCode(), group4.hashCode()); assertEquals(group3,group4);