Commit a95c2d5b authored by Jeff Burke's avatar Jeff Burke
Browse files

s1840: added approvePendingUser method.

parent 371d72ad
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -92,8 +92,6 @@
  <property name="cadcRegistry" value="${lib}/cadcRegistryClient.jar"/>
  <property name="cadcUtil" value="${lib}/cadcUtil.jar"/>
  <property name="cadcUWS" value="${lib}/cadcUWS.jar"/>
  <property name="wsUtil" value="${lib}/wsUtil.jar"/>
  <property name="wsUtil-augment" value="${lib}/wsUtil-augment.jar"/>

  <property name="javacsv" value="${ext.lib}/javacsv.jar"/>
  <property name="jdom2" value="${ext.lib}/jdom2.jar"/>
@@ -103,7 +101,7 @@
  <property name="xerces" value="${ext.lib}/xerces.jar"/>

  <property name="jars"
            value="${javacsv}:${jdom2}:${log4j}:${servlet}:${unboundid}:${xerces}:${cadcAccessControl}:${cadcLog}:${cadcRegistry}:${cadcUtil}:${cadcUWS}:${wsUtil}:${wsUtil-augment}"/>
            value="${javacsv}:${jdom2}:${log4j}:${servlet}:${unboundid}:${xerces}:${cadcAccessControl}:${cadcLog}:${cadcRegistry}:${cadcUtil}:${cadcUWS}"/>

  <target name="build" depends="compile">
    <jar jarfile="${build}/lib/${project}.jar"
+17 −1
Original line number Diff line number Diff line
@@ -175,7 +175,23 @@ public interface UserPersistence<T extends Principal>
        throws TransientException, AccessControlException;

    /**
     * Updated the user specified by userID in the active users tree.
     * Move the pending user specified by userID from the
     * pending users tree to the active users tree.
     *
     * @param userID      The userID.
     *
     * @return User instance.
     *
     * @throws UserNotFoundException when the user is not found.
     * @throws TransientException If an temporary, unexpected problem occurred.
     * @throws AccessControlException If the operation is not permitted.
     */
    User<T> approvePendingUser(T userID)
        throws UserNotFoundException, TransientException,
        AccessControlException;

    /**
     * Update the user specified by userID in the active users tree.
     *
     * @param user      The user instance to modify.
     *
+58 −8
Original line number Diff line number Diff line
@@ -77,10 +77,12 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.security.auth.x500.X500Principal;

import ca.nrc.cadc.auth.DNPrincipal;
import com.unboundid.ldap.sdk.ModifyDNRequest;
import org.apache.log4j.Logger;

import ca.nrc.cadc.ac.PersonalDetails;
@@ -611,21 +613,69 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
    }

    /**
     * Updated the user specified by User.
     * Move the pending user specified by userID from the
     * pending users tree to the active users tree.
     *
     * @param user
     * @param userID
     * @return User instance.
     * @throws UserNotFoundException  when the user is not found.
     * @throws TransientException     If an temporary, unexpected problem occurred.
     * @throws AccessControlException If the operation is not permitted.
     */
    public User<T> approvePendingUser(final T userID)
        throws UserNotFoundException, TransientException, AccessControlException
    {
        User<T> pendingUser = getPendingUser(userID);

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

        try
        {
            ModifyDNRequest modifyDNRequest =
                new ModifyDNRequest(dn, uid, false, config.getUsersDN());

            LdapDAO.checkLdapResult(getConnection().modifyDN(modifyDNRequest).getResultCode());
        }
        catch (LDAPException e)
        {
            e.printStackTrace();
            logger.debug("Modify Exception: " + e, e);
            LdapDAO.checkLdapResult(e.getResultCode());
        }
        try
        {
            return getUser(userID);
        }
        catch (UserNotFoundException e)
        {
            throw new RuntimeException(
                "BUG: approved user not found (" + userID.getName() + ")");
        }
    }

    /**
     * Update the user specified by User.
     *
     * @param userID
     * @return User instance.
     * @throws UserNotFoundException  when the user is not found.
     * @throws TransientException     If an temporary, unexpected problem occurred.
     * @throws AccessControlException If the operation is not permitted.
     */
    public User<T> modifyUser(final User<T> user)
    public User<T> modifyUser(final User<T> userID)
            throws UserNotFoundException, TransientException, AccessControlException
    {
        User existingUser = getUser(user.getUserID());
        User existingUser = getUser(userID.getUserID());

        List<Modification> mods = new ArrayList<Modification>();
        for (UserDetails details : user.details)
        for (UserDetails details : userID.details)
        {
            if (details.getClass() == PersonalDetails.class)
            {
@@ -647,7 +697,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO

        try
        {
            ModifyRequest modifyRequest = new ModifyRequest(getUserDN(user), mods);
            ModifyRequest modifyRequest = new ModifyRequest(getUserDN(userID), mods);
            modifyRequest.addControl(
                new ProxiedAuthorizationV2RequestControl(
                    "dn:" + getSubjectDN().toNormalizedString()));
@@ -661,12 +711,12 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
        }
        try
        {
            return getUser(user.getUserID());
            return getUser(userID.getUserID());
        }
        catch (UserNotFoundException e)
        {
            throw new RuntimeException(
                "BUG: modified user not found (" + user.getUserID() + ")");
                "BUG: modified user not found (" + userID.getUserID() + ")");
        }
    }

+31 −0
Original line number Diff line number Diff line
@@ -291,6 +291,37 @@ public class LdapUserPersistence<T extends Principal> implements UserPersistenc
        }
    }

    /**
     * Move the pending user specified by userID from the
     * pending users tree to the active users tree.
     *
     * @param userID      The user instance to move.
     *
     * @return User instance.
     *
     * @throws UserNotFoundException when the user is not found.
     * @throws TransientException If an temporary, unexpected problem occurred.
     * @throws AccessControlException If the operation is not permitted.
     */
    public User<T> approvePendingUser(T userID)
        throws UserNotFoundException, TransientException,
        AccessControlException
    {
        LdapUserDAO<T> userDAO = null;
        try
        {
            userDAO = new LdapUserDAO<T>(this.config);
            return userDAO.approvePendingUser(userID);
        }
        finally
        {
            if (userDAO != null)
            {
                userDAO.close();
            }
        }
    }

    /**
     * Updated the user specified by userID in the active users tree.
     *
+65 −18
Original line number Diff line number Diff line
@@ -94,7 +94,6 @@ 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;
@@ -170,7 +169,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
        };
    }

    String createUserID()
    String createUsername()
    {
        return "CadcDaoTestUser-" + System.currentTimeMillis();
    }
@@ -181,14 +180,14 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
    @Test
    public void testAddUser() throws Exception
    {
        String userID = createUserID();
        String username = createUsername();

        HttpPrincipal httpPrincipal = new HttpPrincipal(userID);
        X500Principal x500Principal = new X500Principal("cn=" + userID + ",ou=cadc,o=hia,c=ca");
        HttpPrincipal userID = new HttpPrincipal(username);
        X500Principal x500Principal = new X500Principal("cn=" + username + ",ou=cadc,o=hia,c=ca");
        NumericPrincipal numericPrincipal = new NumericPrincipal(ran.nextInt(Integer.MAX_VALUE));

        final User<Principal> expected = new User<Principal>(httpPrincipal);
        expected.getIdentities().add(httpPrincipal);
        final User<Principal> expected = new User<Principal>(userID);
        expected.getIdentities().add(userID);
        expected.getIdentities().add(x500Principal);
        expected.getIdentities().add(numericPrincipal);

@@ -200,7 +199,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
        final LdapUserDAO<Principal> userDAO = getUserDAO();
        userDAO.addUser(userRequest);

        DNPrincipal dnPrincipal = new DNPrincipal("uid=" + userID + "," + config.getUsersDN());
        DNPrincipal dnPrincipal = new DNPrincipal("uid=" + username + "," + config.getUsersDN());
        Subject subject = new Subject();
        subject.getPrincipals().add(dnPrincipal);

@@ -232,14 +231,14 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
    @Test
    public void testAddPendingUser() throws Exception
    {
        String userID = createUserID();
        String username = createUsername();

        HttpPrincipal httpPrincipal = new HttpPrincipal(userID);
        X500Principal x500Principal = new X500Principal("cn=" + userID + ",ou=cadc,o=hia,c=ca");
        HttpPrincipal userID = new HttpPrincipal(username);
        X500Principal x500Principal = new X500Principal("cn=" + username + ",ou=cadc,o=hia,c=ca");
        NumericPrincipal numericPrincipal = new NumericPrincipal(ran.nextInt(Integer.MAX_VALUE));

        final User<Principal> expected = new User<Principal>(httpPrincipal);
        expected.getIdentities().add(httpPrincipal);
        final User<Principal> expected = new User<Principal>(userID);
        expected.getIdentities().add(userID);
        expected.getIdentities().add(x500Principal);
        expected.getIdentities().add(numericPrincipal);

@@ -251,7 +250,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
        final LdapUserDAO<Principal> userDAO = getUserDAO();
        userDAO.addPendingUser(userRequest);

        DNPrincipal dnPrincipal = new DNPrincipal("uid=" + userID + "," + config.getUserRequestsDN());
        DNPrincipal dnPrincipal = new DNPrincipal("uid=" + username + "," + config.getUserRequestsDN());
        Subject subject = new Subject();
        subject.getPrincipals().add(dnPrincipal);

@@ -340,12 +339,60 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
        });
    }

    @Test
    public void testApproveUser() throws Exception
    {
        String username = createUsername();

        HttpPrincipal userID = new HttpPrincipal(username);
        X500Principal x500Principal = new X500Principal("cn=" + username + ",ou=cadc,o=hia,c=ca");
        NumericPrincipal numericPrincipal = new NumericPrincipal(ran.nextInt(Integer.MAX_VALUE));

        final User<Principal> expected = new User<Principal>(userID);
        expected.getIdentities().add(userID);
        expected.getIdentities().add(x500Principal);
        expected.getIdentities().add(numericPrincipal);

        expected.details.add(new PersonalDetails("foo", "bar"));

        final UserRequest<Principal> userRequest =
            new UserRequest<Principal>(expected, "123456".toCharArray());

        final LdapUserDAO<Principal> userDAO = getUserDAO();
        userDAO.addPendingUser(userRequest);

        DNPrincipal dnPrincipal = new DNPrincipal("uid=" + username + "," + config.getUsersDN());
        Subject subject = new Subject();
        subject.getPrincipals().add(dnPrincipal);

        // do everything as owner
        Subject.doAs(subject, new PrivilegedExceptionAction<Object>()
        {
            public Object run() throws Exception
            {
                try
                {
                    final LdapUserDAO<Principal> userDAO = getUserDAO();
                    final User<Principal> actual = userDAO.approvePendingUser(expected.getUserID());
                    assertNotNull(actual);
                    assertEquals(expected.getUserID(), actual.getUserID());

                    return null;
                }
                catch (Exception e)
                {
                    throw new Exception("Problems", e);
                }
            }
        });
    }

    @Test
    public void testUpdateUser() throws Exception
    {
        // Create a test user
        final User<HttpPrincipal> testUser2;
        final String username = createUserID();
        final String username = createUsername();
        final char[] password = "foo".toCharArray();

        HttpPrincipal principal = new HttpPrincipal(username);
@@ -447,7 +494,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
    @Test
    public void deleteUser() throws Exception
    {
        String userID = createUserID();
        String userID = createUsername();

        HttpPrincipal httpPrincipal = new HttpPrincipal(userID);
        X500Principal x500Principal = new X500Principal("cn=" + userID + ",ou=cadc,o=hia,c=ca");
@@ -493,7 +540,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
    @Test
    public void deletePendingUser() throws Exception
    {
        String userID = createUserID();
        String userID = createUsername();

        HttpPrincipal httpPrincipal = new HttpPrincipal(userID);
        X500Principal x500Principal = new X500Principal("cn=" + userID + ",ou=cadc,o=hia,c=ca");
@@ -754,7 +801,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest

        // Create a test user with a known password
        final User<HttpPrincipal> testUser2;
        final String username = createUserID();
        final String username = createUsername();
        final char[] password = "foo".toCharArray();
        final char[] newPassword = "bar".toCharArray();