From ac8df62baa01a292daaefc8b3a09fd9c7f4068b1 Mon Sep 17 00:00:00 2001 From: Alinga Yeung <Alinga.Yeung@nrc-cnrc.gc.ca> Date: Thu, 20 Aug 2015 13:44:19 -0700 Subject: [PATCH] Story ac2. Reverted changes made by git :-) --- .../nrc/cadc/ac/server/ldap/LdapUserDAO.java | 81 ++++++++++---- .../server/web/users/UserActionFactory.java | 10 +- .../cadc/ac/server/ldap/LdapUserDAOTest.java | 101 +++++++++++++----- 3 files changed, 138 insertions(+), 54 deletions(-) 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 772c6531..219728d8 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 @@ -68,6 +68,20 @@ */ package ca.nrc.cadc.ac.server.ldap; +import java.security.AccessControlException; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import javax.security.auth.x500.X500Principal; + +import org.apache.log4j.Logger; + import ca.nrc.cadc.ac.PersonalDetails; import ca.nrc.cadc.ac.PosixDetails; import ca.nrc.cadc.ac.User; @@ -77,6 +91,7 @@ import ca.nrc.cadc.ac.UserNotFoundException; import ca.nrc.cadc.ac.UserRequest; import ca.nrc.cadc.auth.AuthenticationUtil; import ca.nrc.cadc.auth.HttpPrincipal; +import ca.nrc.cadc.auth.NumericPrincipal; import ca.nrc.cadc.net.TransientException; import com.unboundid.ldap.sdk.AddRequest; import com.unboundid.ldap.sdk.Attribute; @@ -100,17 +115,7 @@ import com.unboundid.ldap.sdk.SimpleBindRequest; import com.unboundid.ldap.sdk.controls.ProxiedAuthorizationV2RequestControl; import com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedRequest; import com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedResult; -import org.apache.log4j.Logger; -import javax.security.auth.x500.X500Principal; -import java.security.AccessControlException; -import java.security.Principal; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; public class LdapUserDAO<T extends Principal> extends LdapDAO @@ -130,6 +135,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO protected static final String LDAP_ENTRYDN = "entrydn"; protected static final String LDAP_COMMON_NAME = "cn"; protected static final String LDAP_DISTINGUISHED_NAME = "distinguishedName"; + protected static final String LDAP_NUMERICID = "numericid"; protected static final String LADP_USER_PASSWORD = "userPassword"; protected static final String LDAP_FIRST_NAME = "givenName"; protected static final String LDAP_LAST_NAME = "sn"; @@ -140,11 +146,12 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO protected static final String LDAP_INSTITUTE = "institute"; protected static final String LDAP_UID = "uid"; + private String[] userAttribs = new String[] { LDAP_FIRST_NAME, LDAP_LAST_NAME, LDAP_ADDRESS, LDAP_CITY, LDAP_COUNTRY, - LDAP_EMAIL, LDAP_INSTITUTE, LDAP_UID + LDAP_EMAIL, LDAP_INSTITUTE }; private String[] memberAttribs = new String[] { @@ -156,6 +163,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO super(config); this.userLdapAttrib.put(HttpPrincipal.class, LDAP_UID); this.userLdapAttrib.put(X500Principal.class, LDAP_DISTINGUISHED_NAME); + this.userLdapAttrib.put(NumericPrincipal.class, LDAP_NUMERICID); // add the id attributes to user and member attributes String[] princs = userLdapAttrib.values() @@ -351,17 +359,26 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO try { // add new user + + DN userX500DN = getUserRequestsDN(user.getUserID().getName()); List<Attribute> attributes = new ArrayList<Attribute>(); addAttribute(attributes, LDAP_OBJECT_CLASS, LDAP_INET_ORG_PERSON); addAttribute(attributes, LDAP_OBJECT_CLASS, LDAP_INET_USER); addAttribute(attributes, LDAP_OBJECT_CLASS, LDAP_CADC_ACCOUNT); addAttribute(attributes, LDAP_COMMON_NAME, user.getUserID() .getName()); - addAttribute(attributes, LDAP_DISTINGUISHED_NAME, userDN - .toNormalizedString()); - addAttribute(attributes, LADP_USER_PASSWORD, - String.valueOf(userRequest.getPassword())); - + addAttribute(attributes, LADP_USER_PASSWORD, new String(userRequest + .getPassword())); + addAttribute(attributes, LDAP_NUMERICID, + String.valueOf(genNextNumericId())); + for (Principal princ : user.getIdentities()) + { + if (princ instanceof X500Principal) + { + addAttribute(attributes, LDAP_DISTINGUISHED_NAME, + princ.getName()); + } + } for (UserDetails details : user.details) { if (details.getClass() == PersonalDetails.class) @@ -449,7 +466,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO "Unsupported principal type " + userID.getClass()); } - searchField = "(&(objectclass=inetorgperson)(" + + searchField = "(&(objectclass=inetorgperson)(objectclass=cadcaccount)(" + searchField + "=" + userID.getName() + "))"; logger.debug(searchField); @@ -459,7 +476,6 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO SearchRequest searchRequest = new SearchRequest(usersDN, SearchScope.SUB, searchField, userAttribs); - if (isSecure(usersDN)) { searchRequest.addControl( @@ -480,10 +496,17 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO logger.debug(msg); throw new UserNotFoundException(msg); } - User<T> user = new User<T>(userID); - user.getIdentities().add(new HttpPrincipal(searchResult.getAttributeValue( - userLdapAttrib.get(HttpPrincipal.class)))); + User<T> user = new User<T>(userID); + user.getIdentities().add(new HttpPrincipal( + searchResult.getAttributeValue( + userLdapAttrib.get(HttpPrincipal.class)))); + user.getIdentities().add(new NumericPrincipal( + searchResult.getAttributeValueAsLong( + userLdapAttrib.get(NumericPrincipal.class)))); + user.getIdentities().add(new X500Principal( + searchResult.getAttributeValue( + userLdapAttrib.get(X500Principal.class)))); String fname = searchResult.getAttributeValue(LDAP_FIRST_NAME); String lname = searchResult.getAttributeValue(LDAP_LAST_NAME); PersonalDetails personaDetails = new PersonalDetails(fname, lname); @@ -793,10 +816,9 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO "Unsupported principal type " + userID.getClass()); } - User<T> user = getUser(userID); Filter filter = Filter.createANDFilter( Filter.createEqualityFilter(searchField, - user.getUserID().getName()), + userID.getName()), Filter.createEqualityFilter(LDAP_MEMBEROF, groupID)); SearchRequest searchRequest = @@ -993,4 +1015,17 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO LdapDAO.checkLdapResult(code); } } + + /** + * Method to return a randomly generated user numeric ID. The default + * implementation returns a value between 10000 and Integer.MAX_VALUE. + * Services that support a different mechanism for generating numeric + * IDs overide this method. + * @return + */ + protected int genNextNumericId() + { + Random rand = new Random(); + return rand.nextInt(Integer.MAX_VALUE - 10000) + 10000; + } } diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java index ce45a74e..6c7b0c33 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java @@ -234,24 +234,24 @@ public abstract class UserActionFactory { throw new IllegalArgumentException("User endpoint missing idType parameter"); } - else if (idType.equals(IdentityType.USERNAME.getValue())) + else if (idType.equalsIgnoreCase(IdentityType.USERNAME.getValue())) { return new User<HttpPrincipal>(new HttpPrincipal(userName)); } - else if (idType.equals(IdentityType.X500.getValue())) + else if (idType.equalsIgnoreCase(IdentityType.X500.getValue())) { return new User<X500Principal>(new X500Principal(userName)); } - else if (idType.equals(IdentityType.UID.getValue())) + else if (idType.equalsIgnoreCase(IdentityType.UID.getValue())) { return new User<NumericPrincipal>(new NumericPrincipal( Long.parseLong(userName))); } - else if (idType.equals(IdentityType.OPENID.getValue())) + else if (idType.equalsIgnoreCase(IdentityType.OPENID.getValue())) { return new User<OpenIdPrincipal>(new OpenIdPrincipal(userName)); } - else if (idType.equals(IdentityType.COOKIE.getValue())) + else if (idType.equalsIgnoreCase(IdentityType.COOKIE.getValue())) { return new User<CookiePrincipal>(new CookiePrincipal(userName)); } 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 4226915a..cb143e90 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 @@ -68,41 +68,49 @@ */ package ca.nrc.cadc.ac.server.ldap; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.security.Principal; +import java.security.PrivilegedExceptionAction; +import java.util.Collection; +import java.util.Random; + +import javax.security.auth.Subject; +import javax.security.auth.x500.X500Principal; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.junit.BeforeClass; +import org.junit.Test; + import ca.nrc.cadc.ac.PersonalDetails; import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.UserDetails; import ca.nrc.cadc.ac.UserRequest; import ca.nrc.cadc.auth.HttpPrincipal; +import ca.nrc.cadc.auth.NumericPrincipal; import ca.nrc.cadc.net.TransientException; import ca.nrc.cadc.util.Log4jInit; -import com.unboundid.ldap.sdk.DN; -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.junit.BeforeClass; -import org.junit.Test; -import javax.security.auth.Subject; -import javax.security.auth.x500.X500Principal; -import java.security.Principal; -import java.security.PrivilegedExceptionAction; -import java.util.Collection; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import com.unboundid.ldap.sdk.DN; public class LdapUserDAOTest extends AbstractLdapDAOTest { private static final Logger log = Logger.getLogger(LdapUserDAOTest.class); static final String testUserX509DN = "cn=cadcdaotest1,ou=cadc,o=hia,c=ca"; + static int nextUserNumericID = 666; static String testUserDN; static User<X500Principal> testUser; + static User<X500Principal> testMember; static User<HttpPrincipal> testPendingUser; static LdapConfig config; + static Random ran = new Random(); // source of randomness for numeric ids @BeforeClass @@ -113,23 +121,43 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest // get the configuration of the development server from and config files... config = getLdapConfig(); + X500Principal testUserX500Princ = new X500Principal(testUserX509DN); + testUser = new User<X500Principal>(testUserX500Princ); testPendingUser = new User<HttpPrincipal>(new HttpPrincipal("CADCtestRequest")); testPendingUser.details.add(new PersonalDetails("CADCtest", "Request")); testPendingUser.getIdentities().add( new HttpPrincipal("CADCtestRequest")); + testPendingUser.getIdentities().add( + new X500Principal( + "uid=CADCtestRequest,ou=userrequests,ou=ds,dc=testcanfar")); + testPendingUser.getIdentities().add(new NumericPrincipal(66666)); - testUser = new User<X500Principal>(new X500Principal(testUserX509DN)); testUser.details.add(new PersonalDetails("CADC", "DAOTest1")); testUser.getIdentities().add(new HttpPrincipal("CadcDaoTest1")); + testUser.getIdentities().add(testUserX500Princ); + testUser.getIdentities().add(new NumericPrincipal(666)); testUserDN = "uid=cadcdaotest1," + config.getUsersDN(); + + + // member returned by getMember contains only the fields required by + // the GMS + testMember = new User<X500Principal>(testUserX500Princ); + testMember.details.add(new PersonalDetails("CADC", "DAOTest1")); + testMember.getIdentities().add(new HttpPrincipal("CadcDaoTest1")); + } <T extends Principal> LdapUserDAO<T> getUserDAO() throws Exception { - return new LdapUserDAO<T>(config); + return new LdapUserDAO(config){ + protected int genNextNumericId() + { + return nextUserNumericID; + } + }; } String createUserID() @@ -143,9 +171,13 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest @Test public void testAddUser() throws Exception { - final User<HttpPrincipal> expected = - new User<HttpPrincipal>(new HttpPrincipal(createUserID())); - expected.getIdentities().add(new HttpPrincipal(createUserID())); + String userID = createUserID(); + final User<HttpPrincipal> expected = new User<HttpPrincipal>(new HttpPrincipal(userID)); + expected.getIdentities().add(new HttpPrincipal(userID)); + expected.getIdentities().add(new X500Principal("cn=" + userID + ",ou=cadc,o=hia,c=ca")); + nextUserNumericID = ran.nextInt(Integer.MAX_VALUE); + expected.getIdentities().add(new NumericPrincipal(nextUserNumericID)); + expected.details.add(new PersonalDetails("foo", "bar")); final UserRequest<HttpPrincipal> userRequest = @@ -304,6 +336,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest Subject subject = new Subject(); subject.getPrincipals().add(testUser.getUserID()); + // do everything as owner Subject.doAs(subject, new PrivilegedExceptionAction<Object>() { @@ -312,7 +345,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest try { User<X500Principal> actual = getUserDAO().getX500User(new DN(testUserDN)); - check(testUser, actual); + check(testMember, actual); return null; } catch (Exception e) @@ -335,7 +368,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest try { User<X500Principal> actual = getUserDAO().getX500User(new DN(testUserDN)); - check(testUser, actual); + check(testMember, actual); return null; } catch (Exception e) @@ -535,6 +568,10 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest HttpPrincipal principal = new HttpPrincipal(username); testUser2 = new User<HttpPrincipal>(principal); testUser2.getIdentities().add(principal); + testUser2.getIdentities().add(new X500Principal("cn=" + username + ",ou=cadc,o=hia,c=ca")); + // update nextNumericId + nextUserNumericID = ran.nextInt(Integer.MAX_VALUE); + testUser2.getIdentities().add(new NumericPrincipal(nextUserNumericID)); testUser2.details.add(new PersonalDetails("firstName", "lastName")); final UserRequest<HttpPrincipal> userRequest = new UserRequest<HttpPrincipal>(testUser2, password); @@ -625,9 +662,21 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest assertEquals(user1, user2); assertEquals(user1.details, user2.details); assertEquals(user1.details.size(), user2.details.size()); - assertEquals("Identities don't match.", user1.getIdentities(), - user2.getIdentities()); - for (UserDetails d1 : user1.details) + assertEquals(user1.getIdentities().size(), user2.getIdentities().size()); + for( Principal princ1 : user1.getIdentities()) + { + boolean found = false; + for( Principal princ2 : user2.getIdentities()) + { + if (princ2.getClass() == princ1.getClass()) + { + assertEquals(princ1, princ2); + found = true; + } + } + assertTrue(princ1.getName(), found); + } + for(UserDetails d1 : user1.details) { assertTrue(user2.details.contains(d1)); if (d1 instanceof PersonalDetails) -- GitLab