Commit 18fe2524 authored by Brian Major's avatar Brian Major
Browse files

Merge branch 's1890' of ssh://gimli2/srv/cadc/git/ac into s1890

parents b52ceefe 6a68dd5b
Loading
Loading
Loading
Loading
+61 −36
Original line number Diff line number Diff line
@@ -145,6 +145,10 @@ public class LdapUserDAO extends LdapDAO
    // Map of identity type to LDAP attribute
    private final Map<Class<?>, String> userLdapAttrib = new HashMap<Class<?>, String>();

    // User cn and sn values for users without a HttpPrincipal
    protected static final String EXTERNAL_USER_CN = "$EXTERNAL-CN";
    protected static final String EXTERNAL_USER_SN = "$EXTERNAL-SN";

    // LDAP User attributes
    protected static final String LDAP_OBJECT_CLASS = "objectClass";
    protected static final String LDAP_INET_USER = "inetuser";
@@ -219,8 +223,11 @@ public class LdapUserDAO extends LdapDAO
    {
        try
        {
            HttpPrincipal httpPrincipal = new HttpPrincipal(username);
            User user = getUser(httpPrincipal);
            long id = user.getID().getUUID().getLeastSignificantBits();
            BindRequest bindRequest = new SimpleBindRequest(
                getUserDN(username, config.getUsersDN()), new String(password));
                getUserDN(String.valueOf(id), config.getUsersDN()), new String(password));

            LDAPConnection conn = this.getUnboundReadConnection();
            BindResult bindResult = conn.bind(bindRequest);
@@ -234,6 +241,10 @@ public class LdapUserDAO extends LdapDAO
                throw new AccessControlException("Invalid username or password");
            }
        }
        catch (UserNotFoundException e)
        {
            throw new AccessControlException("Invalid username");
        }
        catch (LDAPException e)
        {
            logger.debug("doLogin Exception: " + e, e);
@@ -321,8 +332,12 @@ public class LdapUserDAO extends LdapDAO
        try
        {
            String emailAddress = getEmailAddress(userRequest);
            Principal userID = getSupportedPrincipal(userRequest.getUser());
            if (userID instanceof HttpPrincipal)
            {
                getUserByEmailAddress(emailAddress, usersDN);
            }
        }
        catch (UserNotFoundException ok) { }
    }

@@ -370,23 +385,29 @@ public class LdapUserDAO extends LdapDAO
            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);
            if (user.getHttpPrincipal() != null)
            {
                addAttribute(attributes, LDAP_COMMON_NAME, userID.getName());
            }
            addAttribute(attributes, LADP_USER_PASSWORD, new String(userRequest.getPassword()));
            addAttribute(attributes, LDAP_UID, numericID);
            addAttribute(attributes, LADP_USER_PASSWORD, new String(userRequest.getPassword()));

            for (Principal princ : user.getIdentities())
            {
                if (princ instanceof X500Principal)
            if (user.getHttpPrincipal() == null)
            {
                    addAttribute(attributes, LDAP_DISTINGUISHED_NAME, princ.getName());
                addAttribute(attributes, LDAP_COMMON_NAME, EXTERNAL_USER_CN);
                addAttribute(attributes, LDAP_LAST_NAME, EXTERNAL_USER_SN);
            }
            else
            {
                if (user.personalDetails == null)
                {
                    final String error = "User " + user.getHttpPrincipal().getName() +
                        " missing required PersonalDetails";
                    throw new IllegalArgumentException(error);
                }

            if (user.personalDetails != null)
                 if (userID.getName().startsWith("$"))
                 {
                     final String error = "Username " + user.getHttpPrincipal().getName() +
                         " cannot start with a $";
                     throw new IllegalArgumentException(error);
                 }
                addAttribute(attributes, LDAP_COMMON_NAME, userID.getName());
                addAttribute(attributes, LDAP_FIRST_NAME, user.personalDetails.getFirstName());
                addAttribute(attributes, LDAP_LAST_NAME, user.personalDetails.getLastName());
                addAttribute(attributes, LDAP_ADDRESS, user.personalDetails.address);
@@ -396,6 +417,14 @@ public class LdapUserDAO extends LdapDAO
                addAttribute(attributes, LDAP_INSTITUTE, user.personalDetails.institute);
            }

            for (Principal princ : user.getIdentities())
            {
                if (princ instanceof X500Principal)
                {
                    addAttribute(attributes, LDAP_DISTINGUISHED_NAME, princ.getName());
                }
            }

            if (user.posixDetails != null)
            {
                throw new UnsupportedOperationException("Support for users PosixDetails not available");
@@ -403,9 +432,9 @@ public class LdapUserDAO extends LdapDAO

            DN userDN = getUserDN(numericID, usersDN);
            AddRequest addRequest = new AddRequest(userDN, attributes);
            logger.info("adding " + userID.getName() + " to " + usersDN);
            LDAPResult result = getReadWriteConnection().add(addRequest);
            LdapDAO.checkLdapResult(result.getResultCode());
            logger.info("added " + userID.getName() + " to " + usersDN);
        }
        catch (LDAPException e)
        {
@@ -493,7 +522,7 @@ public class LdapUserDAO extends LdapDAO
        try
        {
            filter = Filter.createEqualityFilter(searchField, userID.getName());
            logger.debug("search filter: " + filter);
            logger.debug("getUser search filter: " + filter);

            SearchRequest searchRequest =
                    new SearchRequest(usersDN, SearchScope.ONE, filter, userAttribs);
@@ -837,10 +866,10 @@ public class LdapUserDAO extends LdapDAO
            for (SearchResultEntry next : searchResult.getSearchEntries())
            {
                final String firstName =
                    next.getAttributeValue(LDAP_FIRST_NAME).trim();
                    next.getAttributeValue(LDAP_FIRST_NAME);
                final String lastName =
                    next.getAttributeValue(LDAP_LAST_NAME).trim();
                final String uid = next.getAttributeValue(LDAP_UID).trim();
                final String uid = next.getAttributeValue(LDAP_UID);

                User user = new User();
                user.getIdentities().add(new HttpPrincipal(uid));
@@ -849,7 +878,7 @@ public class LdapUserDAO extends LdapDAO
                if (StringUtil.hasLength(firstName) &&
                    StringUtil.hasLength(lastName))
                {
                    user.personalDetails = new PersonalDetails(firstName, lastName);
                    user.personalDetails = new PersonalDetails(firstName.trim(), lastName.trim());
                }

                users.add(user);
@@ -882,14 +911,11 @@ public class LdapUserDAO extends LdapDAO
        throws UserNotFoundException, TransientException, AccessControlException
    {
        User pendingUser = getPendingUser(userID);

        Set<HttpPrincipal> httpPrincipals = pendingUser.getIdentities(HttpPrincipal.class);
        if (httpPrincipals.isEmpty())
        if (pendingUser.getHttpPrincipal() == null)
        {
            throw new RuntimeException("BUG: missing HttpPrincipal for " + userID.getName());
        }
        HttpPrincipal httpPrincipal = httpPrincipals.iterator().next();
        String uid = "uid=" + httpPrincipal.getName();
        String uid = "uid=" + pendingUser.getID().getUUID().getLeastSignificantBits();
        String dn = uid + "," + config.getUserRequestsDN();

        try
@@ -1093,10 +1119,11 @@ public class LdapUserDAO extends LdapDAO
    private void deleteUser(final Principal userID, final String usersDN, boolean markDelete)
        throws UserNotFoundException, AccessControlException, TransientException
    {
        getUser(userID, usersDN);
        User user2Delete = getUser(userID, usersDN);
        try
        {
            DN userDN = getUserDN(userID.getName(), usersDN);
            long id = user2Delete.getID().getUUID().getLeastSignificantBits();
            DN userDN = getUserDN(String.valueOf(id), usersDN);
            if (markDelete)
            {
                List<Modification> modifs = new ArrayList<Modification>();
@@ -1113,11 +1140,9 @@ public class LdapUserDAO extends LdapDAO
            else // real delete
            {
                DeleteRequest delRequest = new DeleteRequest(userDN);
                //delRequest.addControl(
                //    new ProxiedAuthorizationV2RequestControl(
                //        "dn:" + getSubjectDN().toNormalizedString()));

                LDAPResult result = getReadWriteConnection().delete(delRequest);
                logger.info("delete result:" + delRequest);
                LdapDAO.checkLdapResult(result.getResultCode());
            }
        }
@@ -1348,13 +1373,13 @@ public class LdapUserDAO extends LdapDAO
        }

        // Another supported Principal
        for (Principal principal : user.getIdentities())
        {
            if (userLdapAttrib.get(principal.getClass()) != null)
            {
                return principal;
            }
        }
//        for (Principal principal : user.getIdentities())
//        {
//            if (userLdapAttrib.get(principal.getClass()) != null)
//            {
//                return principal;
//            }
//        }
        return null;
    }

+24 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@
package ca.nrc.cadc.ac.server.web.groups;

import java.io.IOException;
import java.lang.reflect.Field;
import java.security.AccessControlException;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
@@ -232,4 +233,27 @@ public abstract class AbstractGroupAction implements PrivilegedExceptionAction<O
        this.logInfo.deletedMembers = deletedMembers;
    }

    // set private field using reflection
    protected void setField(Object object, Object value, String name)
    {
        try
        {
            Field field = object.getClass().getDeclaredField(name);
            field.setAccessible(true);
            field.set(object, value);
        }
        catch (NoSuchFieldException e)
        {
            final String error = object.getClass().getSimpleName() +
                " field " + name + "not found";
            throw new RuntimeException(error, e);
        }
        catch (IllegalAccessException e)
        {
            final String error = "unable to update " + name + " in " +
                object.getClass().getSimpleName();
            throw new RuntimeException(error, e);
        }
    }

}
+1 −7
Original line number Diff line number Diff line
@@ -102,13 +102,7 @@ public class RemoveUserMemberAction extends AbstractGroupAction
        Group group = groupPersistence.getGroup(this.groupName);

        Principal userPrincipal = AuthenticationUtil.createPrincipal(this.userID, this.userIDType);
        User user = getUserPersistence().getAugmentedUser(userPrincipal);
        Set<X500Principal> x500Principals = user.getIdentities(X500Principal.class);
        X500Principal x500Principal = x500Principals.iterator().next();
        User toRemove = new User();
        toRemove.getIdentities().add(x500Principal);

        // User members is a Set of User<X500Principal>
        User toRemove = getUserPersistence().getUser(userPrincipal);
        if (!group.getUserMembers().remove(toRemove))
        {
            throw new MemberNotFoundException();
+163 −0
Original line number Diff line number Diff line
@@ -67,6 +67,22 @@

package ca.nrc.cadc.ac.server.ldap;

import ca.nrc.cadc.ac.PersonalDetails;
import ca.nrc.cadc.ac.User;
import ca.nrc.cadc.ac.UserNotFoundException;
import ca.nrc.cadc.ac.UserRequest;
import ca.nrc.cadc.auth.DNPrincipal;
import ca.nrc.cadc.auth.HttpPrincipal;
import ca.nrc.cadc.auth.NumericPrincipal;
import ca.nrc.cadc.util.Log4jInit;
import org.apache.log4j.Level;
import org.junit.BeforeClass;

import javax.security.auth.Subject;
import javax.security.auth.x500.X500Principal;
import java.lang.reflect.Field;
import java.util.UUID;

/**
 * Created by jburke on 2014-11-03.
 */
@@ -74,9 +90,156 @@ public class AbstractLdapDAOTest
{
    static final String CONFIG = LdapConfig.class.getSimpleName() + ".test.properties";

    protected static final String SERVOPS_PEM = System.getProperty("user.home") + "/.pub/proxy.pem";
    static final String cadcDaoTest1_CN = "CadcDaoTest1";
    static final String cadcDaoTest2_CN = "CadcDaoTest2";
    static final String cadcDaoTest3_CN = "CadcDaoTest3";
    static final String cadcDaoTest1_X500DN = "cn=cadcdaotest1,ou=cadc,o=hia,c=ca";
    static final String cadcDaoTest2_X500DN = "cn=cadcdaotest2,ou=cadc,o=hia,c=ca";
    static final String cadcDaoTest3_X500DN = "cn=cadcdaotest3,ou=cadc,o=hia,c=ca";

    static User cadcDaoTest1_User;
    static User cadcDaoTest2_User;
    static User cadcDaoTest3_User;
    static User cadcDaoTest1_HttpUser;
    static User cadcDaoTest1_X500User;
    static User cadcDaoTest1_AugmentedUser;
    static User cadcDaoTest2_AugmentedUser;
    static User testMember;

    static String cadcDaoTest1_DN;
    static String cadcDaoTest2_DN;

    static HttpPrincipal cadcDaoTest1_HttpPrincipal;
    static HttpPrincipal cadcDaoTest2_HttpPrincipal;
    static HttpPrincipal cadcDaoTest3_HttpPrincipal;
    static X500Principal cadcDaoTest1_X500Principal;
    static X500Principal cadcDaoTest2_X500Principal;
    static X500Principal cadcDaoTest3_X500Principal;
    static DNPrincipal cadcDaoTest1_DNPrincipal;
    static DNPrincipal cadcDaoTest2_DNPrincipal;

    static Subject cadcDaoTest1_Subject;
    static Subject cadcDaoTest2_Subject;

    static LdapConfig config;

    @BeforeClass
    public static void setUpBeforeClass()
        throws Exception
    {
        Log4jInit.setLevel("ca.nrc.cadc.ac", Level.DEBUG);

        // get the configuration of the development server from and config files...
        config = getLdapConfig();

        cadcDaoTest1_HttpPrincipal = new HttpPrincipal(cadcDaoTest1_CN);
        cadcDaoTest2_HttpPrincipal = new HttpPrincipal(cadcDaoTest2_CN);
        cadcDaoTest3_HttpPrincipal = new HttpPrincipal(cadcDaoTest3_CN);

        cadcDaoTest1_X500Principal = new X500Principal(cadcDaoTest1_X500DN);
        cadcDaoTest2_X500Principal = new X500Principal(cadcDaoTest2_X500DN);
        cadcDaoTest3_X500Principal = new X500Principal(cadcDaoTest3_X500DN);

        try
        {
            cadcDaoTest1_User = getUserDAO().getUser(cadcDaoTest1_HttpPrincipal);
        }
        catch (UserNotFoundException e)
        {
            User user = new User();
            user.getIdentities().add(cadcDaoTest1_HttpPrincipal);
            user.getIdentities().add(cadcDaoTest1_X500Principal);
            user.personalDetails = new PersonalDetails("CADC", "DAOTest1");
            user.personalDetails.email = cadcDaoTest1_CN + "@canada.ca";
            UserRequest request = new UserRequest(user, "password1".toCharArray());
            getUserDAO().addUser(request);
            cadcDaoTest1_User = getUserDAO().getUser(cadcDaoTest1_HttpPrincipal);
        }

        try
        {
            cadcDaoTest2_User = getUserDAO().getUser(cadcDaoTest2_HttpPrincipal);
        }
        catch (UserNotFoundException e)
        {
            User user = new User();
            user.getIdentities().add(cadcDaoTest2_HttpPrincipal);
            user.getIdentities().add(cadcDaoTest2_X500Principal);
            user.personalDetails = new PersonalDetails("CADC", "DAOTest2");
            user.personalDetails.email = cadcDaoTest2_CN + "@canada.ca";
            UserRequest request = new UserRequest(user, "password2".toCharArray());
            getUserDAO().addUser(request);
            cadcDaoTest2_User = getUserDAO().getUser(cadcDaoTest2_HttpPrincipal);
        }

        try
        {
            cadcDaoTest3_User = getUserDAO().getUser(cadcDaoTest3_HttpPrincipal);
        }
        catch (UserNotFoundException e)
        {
            User user = new User();
            user.getIdentities().add(cadcDaoTest3_HttpPrincipal);
            user.getIdentities().add(cadcDaoTest3_X500Principal);
            user.personalDetails = new PersonalDetails("CADC", "DAOTest3");
            user.personalDetails.email = cadcDaoTest3_CN + "@canada.ca";
            UserRequest request = new UserRequest(user, "password3".toCharArray());
            getUserDAO().addUser(request);
            cadcDaoTest3_User = getUserDAO().getUser(cadcDaoTest3_HttpPrincipal);
        }

        // cadcDaoTest1 User and Subject with all Principals
        cadcDaoTest1_AugmentedUser = getUserDAO().getAugmentedUser(cadcDaoTest1_HttpPrincipal);
        cadcDaoTest1_Subject = new Subject();
        cadcDaoTest1_Subject.getPrincipals().addAll(cadcDaoTest1_AugmentedUser.getIdentities());

        // cadcDaoTest2 User and Subject with all Principals
        cadcDaoTest2_AugmentedUser = getUserDAO().getAugmentedUser(cadcDaoTest2_HttpPrincipal);
        cadcDaoTest2_Subject = new Subject();
        cadcDaoTest2_Subject.getPrincipals().addAll(cadcDaoTest2_AugmentedUser.getIdentities());

        // A cadcDaoTest1 user with only a HttpPrincipal
//        cadcDaoTest1_HttpUser = new User();
//        cadcDaoTest1_HttpUser.personalDetails = new PersonalDetails("CADC", "DAOTest1");
//        cadcDaoTest1_HttpUser.getIdentities().add(cadcDaoTest1_User.getHttpPrincipal());
//
//        // A cadcDaoTest1 user with only a X500Principal
//        cadcDaoTest1_X500User = new User();
//        cadcDaoTest1_X500User.personalDetails = new PersonalDetails("CADC", "DAOTest1");
//        cadcDaoTest1_X500User.getIdentities().add(cadcDaoTest1_X500Principal);

        // member returned by getMember contains only the fields required by the GMS
        testMember = new User();
        testMember.personalDetails = new PersonalDetails("test", "member");
        testMember.getIdentities().add(cadcDaoTest1_X500Principal);
        testMember.getIdentities().add(cadcDaoTest1_HttpPrincipal);

        // entryDN
        cadcDaoTest1_DN = "uid=cadcdaotest1," + config.getUsersDN();
        cadcDaoTest2_DN = "uid=cadcdaotest2," + config.getUsersDN();

        cadcDaoTest1_DNPrincipal = new DNPrincipal(cadcDaoTest1_DN);
        cadcDaoTest2_DNPrincipal = new DNPrincipal(cadcDaoTest2_DN);
    }

    static LdapUserDAO getUserDAO() throws Exception
    {
        LdapConnections connections = new LdapConnections(config);
        return new LdapUserDAO(connections);
    }

    static protected LdapConfig getLdapConfig()
    {
        return LdapConfig.loadLdapConfig(CONFIG);
    }

    public static void setField(Object object, Object value, String name)
        throws Exception
    {
        Field field = object.getClass().getDeclaredField(name);
        field.setAccessible(true);
        field.set(object, value);
    }

}
+0 −9
Original line number Diff line number Diff line
@@ -96,15 +96,6 @@ import static org.junit.Assert.assertTrue;

public class LdapDAOTest extends AbstractLdapDAOTest
{
    static LdapConfig config;

    @BeforeClass
    public static void setUpBeforeClass() throws Exception
    {
        Log4jInit.setLevel("ca.nrc.cadc.ac", Level.INFO);
        // get the configuration of the development server from and config files...
        config = getLdapConfig();
    }
    @Test
    public void testLdapBindConnection() throws Exception
    {
Loading