Commit 3751b30b authored by Alinga Yeung's avatar Alinga Yeung
Browse files

Story 1840. Updated approve command based on the new UserPersistence...

Story 1840. Updated approve command based on the new UserPersistence interface. Added unit tests. Refactored some codes.
parent 3daa1cbe
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@
    <property name="cadcAccessControl-Server"	value="${lib}/cadcAccessControl-Server.jar" />
    <property name="cadcUtil"			value="${lib}/cadcUtil.jar" />
    <property name="log4j"			value="${ext.lib}/log4j.jar" />
    <property name="commons-logging"            value="${ext.lib}/commons-logging.jar" />
    <property name="unboundid"                  value="${ext.lib}/unboundid-ldapsdk-se.jar" />
    
    <property name="cadc"       value="${cadcAccessControl}:${cadcAccessControl-Server}:${cadcUtil}" />
+39 −25
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ import org.apache.log4j.Logger;
import ca.nrc.cadc.auth.CertCmdArgUtil;
import ca.nrc.cadc.auth.SSLUtil;
import ca.nrc.cadc.util.ArgumentMap;
import ca.nrc.cadc.util.Log4jInit;
import ca.nrc.cadc.util.StringUtil;


@@ -89,23 +90,27 @@ import ca.nrc.cadc.util.StringUtil;
public class CmdLineParser 
{
    private static Logger log = Logger.getLogger(CmdLineParser.class);
    private static final String APP_NAME = "userAdmin";
    private static final String[] LOG_PACKAGES = 
		{"ca.nrc.cadc.ac", "ca.nrc.cadc.auth", "ca.nrc.cadc.util"};

    // no need to proceed further if false
    private Level logLevel = Level.OFF;
    private boolean proceed = true;
    private String appName = "";
    private AbstractCommand command;
    private Subject subject;
    private ArgumentMap am;
    private Level logLevel = Level.DEBUG;

    /**
     * Default constructor.
     * Constructor.
     * @param args Input arguments
     * @throws UsageException Error in command line
     * @throws CertificateException Fail to get a certificate
     */
    public CmdLineParser(final String name, final String[] args) 
    public CmdLineParser(final String[] args) throws UsageException, CertificateException 
    {
    	this.appName = name;    	
        ArgumentMap am = new ArgumentMap( args );
    	this.am = am;
    	this.setLogLevel(am);
    	this.parse(am);
    }
    
    /**
@@ -136,19 +141,19 @@ public class CmdLineParser
    }
    
    /**
     * Get the log level.
     * @throws UsageException 
     * Get the logging level.
     */
    public Level getLogLevel()
    {
    	return this.logLevel;
    }

    /**
     * Get the log level.
    /*
     * Set the log level.
     * @param am Input arguments
     * @throws UsageException 
     */
    public void setLogLevel() throws UsageException
    protected void setLogLevel(final ArgumentMap am) throws UsageException
    {
    	int count = 0;
    	
@@ -167,9 +172,17 @@ public class CmdLineParser
                    	
    	if (count >=2)
    	{
            String msg = "--verbose and --debug are mutually exclusive options\n";            
            String msg = "--verbose and --debug are mutually exclusive options";            
            throw new UsageException(msg);
    	}
    	else
    	{        	
            // set the application log level
            for (String pkg : LOG_PACKAGES)
            {
                Log4jInit.setLevel(APP_NAME, pkg, this.logLevel);
            }
    	}
    }
    
    protected boolean hasValue(final String userID) throws UsageException
@@ -245,29 +258,30 @@ public class CmdLineParser
    		
            if (count == 0)
            {
                msg = "Command is not supported.";
                msg = "Missing command or ommand is not supported.";
            }
            else
            {
                msg = "Only one command can be specified.\n";
                msg = "Only one command can be specified.";
            }
    	
            throw new UsageException(msg);
    	}
    }
    
    /**
    /*
     * Parse the command line arguments.
     * @param ArgumentMap Command line arguments
     * @throws UsageException Error in command line
     * @throws CertificateException 
     * @throws CertificateException Fail to get a certificate
     */
    public void parse() throws UsageException, CertificateException
    protected void parse(final ArgumentMap am) throws UsageException, CertificateException
    {
        this.proceed = false;

        if (!this.am.isSet("h") && !this.am.isSet("help") && isValid(this.am))
        if (!am.isSet("h") && !am.isSet("help") && isValid(am))
        {
            Subject subject = CertCmdArgUtil.initSubject(this.am, true);
            Subject subject = CertCmdArgUtil.initSubject(am, true);
            
            try 
            {
@@ -277,7 +291,7 @@ public class CmdLineParser
            } 
            catch (CertificateException e) 
            {
            	if (this.am.isSet("list"))
            	if (am.isSet("list"))
            	{
                    // we can use anonymous subject
                    this.proceed = true;
@@ -293,11 +307,11 @@ public class CmdLineParser
    /**
     * Provide the default command line usage. 
     */
    public String getUsage()
    public static String getUsage()
    {
    	StringBuilder sb = new StringBuilder();
    	sb.append("\n");
    	sb.append("Usage: " + this.appName + " [--cert=<path to pem file>] <command> [-v|--verbose|-d|--debug] [-h|--help]\n");
    	sb.append("Usage: " + APP_NAME + " [--cert=<path to pem file>] <command> [-v|--verbose|-d|--debug] [-h|--help]\n");
    	sb.append("Where command is\n");
    	sb.append("--list               :list users in the Users tree\n");
    	sb.append("                     :can be executed as an anonymous user\n");
+3 −15
Original line number Diff line number Diff line
@@ -76,8 +76,6 @@ import javax.security.auth.Subject;

import org.apache.log4j.Logger;

import ca.nrc.cadc.util.Log4jInit;

/**
 * A command line admin tool for LDAP users.
 * 
@@ -88,9 +86,6 @@ public class Main
{
    private static Logger log = Logger.getLogger(Main.class);
    
    private static final String APP_NAME = "userAdmin";
    private static final String[] LOG_PACKAGES = 
		{"ca.nrc.cadc.ac", "ca.nrc.cadc.auth", "ca.nrc.cadc.util"};
    private static PrintStream systemOut = System.out;
    private static PrintStream systemErr = System.err;
 
@@ -100,17 +95,10 @@ public class Main
     */
    public static void main(String[] args)
    {
    	CmdLineParser parser = new CmdLineParser(APP_NAME, args);
    	
        try
        {
            parser.setLogLevel();
            for (String pkg : LOG_PACKAGES)
            {
                Log4jInit.setLevel(APP_NAME, pkg, parser.getLogLevel());
            }
        	CmdLineParser parser = new CmdLineParser(args);

            parser.parse();
            if (parser.proceed())
            {  
                AbstractCommand command = parser.getCommand();
@@ -129,13 +117,13 @@ public class Main
            }
            else
            {
                systemOut.println(parser.getUsage());
                systemOut.println(CmdLineParser.getUsage());
            }
        }
        catch(UsageException e)
        {
            systemErr.println("ERROR: " + e.getMessage());
    		systemOut.println(parser.getUsage());
    		systemOut.println(CmdLineParser.getUsage());
            System.exit(0);
        }
        catch(CertificateException e)
+332 −0
Original line number Diff line number Diff line
/*
 ************************************************************************
 *******************  CANADIAN ASTRONOMY DATA CENTRE  *******************
 **************  CENTRE CANADIEN DE DONNÉES ASTRONOMIQUES  **************
 *
 *  (c) 2009.                            (c) 2009.
 *  Government of Canada                 Gouvernement du Canada
 *  National Research Council            Conseil national de recherches
 *  Ottawa, Canada, K1A 0R6              Ottawa, Canada, K1A 0R6
 *  All rights reserved                  Tous droits réservés
 *                                       
 *  NRC disclaims any warranties,        Le CNRC dénie toute garantie
 *  expressed, implied, or               énoncée, implicite ou légale,
 *  statutory, of any kind with          de quelque nature que ce
 *  respect to the software,             soit, concernant le logiciel,
 *  including without limitation         y compris sans restriction
 *  any warranty of merchantability      toute garantie de valeur
 *  or fitness for a particular          marchande ou de pertinence
 *  purpose. NRC shall not be            pour un usage particulier.
 *  liable in any event for any          Le CNRC ne pourra en aucun cas
 *  damages, whether direct or           être tenu responsable de tout
 *  indirect, special or general,        dommage, direct ou indirect,
 *  consequential or incidental,         particulier ou général,
 *  arising from the use of the          accessoire ou fortuit, résultant
 *  software.  Neither the name          de l'utilisation du logiciel. Ni
 *  of the National Research             le nom du Conseil National de
 *  Council of Canada nor the            Recherches du Canada ni les noms
 *  names of its contributors may        de ses  participants ne peuvent
 *  be used to endorse or promote        être utilisés pour approuver ou
 *  products derived from this           promouvoir les produits dérivés
 *  software without specific prior      de ce logiciel sans autorisation
 *  written permission.                  préalable et particulière
 *                                       par écrit.
 *                                       
 *  This file is part of the             Ce fichier fait partie du projet
 *  OpenCADC project.                    OpenCADC.
 *                                       
 *  OpenCADC is free software:           OpenCADC est un logiciel libre ;
 *  you can redistribute it and/or       vous pouvez le redistribuer ou le
 *  modify it under the terms of         modifier suivant les termes de
 *  the GNU Affero General Public        la “GNU Affero General Public
 *  License as published by the          License” telle que publiée
 *  Free Software Foundation,            par la Free Software Foundation
 *  either version 3 of the              : soit la version 3 de cette
 *  License, or (at your option)         licence, soit (à votre gré)
 *  any later version.                   toute version ultérieure.
 *                                       
 *  OpenCADC is distributed in the       OpenCADC est distribué
 *  hope that it will be useful,         dans l’espoir qu’il vous
 *  but WITHOUT ANY WARRANTY;            sera utile, mais SANS AUCUNE
 *  without even the implied             GARANTIE : sans même la garantie
 *  warranty of MERCHANTABILITY          implicite de COMMERCIALISABILITÉ
 *  or FITNESS FOR A PARTICULAR          ni d’ADÉQUATION À UN OBJECTIF
 *  PURPOSE.  See the GNU Affero         PARTICULIER. Consultez la Licence
 *  General Public License for           Générale Publique GNU Affero
 *  more details.                        pour plus de détails.
 *                                       
 *  You should have received             Vous devriez avoir reçu une
 *  a copy of the GNU Affero             copie de la Licence Générale
 *  General Public License along         Publique GNU Affero avec
 *  with OpenCADC.  If not, see          OpenCADC ; si ce n’est
 *  <http://www.gnu.org/licenses/>.      pas le cas, consultez :
 *                                       <http://www.gnu.org/licenses/>.
 *
 *  $Revision: 4 $
 *
 ************************************************************************
 */

package ca.nrc.cadc.ac.admin;

import org.apache.log4j.Level;
import org.junit.Assert;
import org.junit.Test;


/**
 * 
 */
public class CmdLineParserTest
{    
	@Test
	public void testHelp()
	{
		// case 1: short form
    	try
    	{
    	    String[] mArgs = {"-h"};
    	    CmdLineParser parser = new CmdLineParser(mArgs);
    	    Assert.assertEquals(Level.OFF, parser.getLogLevel());
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}
    	
		// case 2: long form
    	try
    	{
    	    String[] mArgs = {"--help"};
    	    CmdLineParser parser = new CmdLineParser(mArgs);
    	    Assert.assertEquals(Level.OFF, parser.getLogLevel());
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}

		// case 3: mixed with a command
    	try
    	{
    	    String[] mArgs = {"--list", "-h"};
    	    CmdLineParser parser = new CmdLineParser(mArgs);
    	    Assert.assertEquals(Level.OFF, parser.getLogLevel());
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}

		// case 4: mixed with a command and log level
    	try
    	{
    	    String[] mArgs = {"--list", "-h", "-v"};
    	    CmdLineParser parser = new CmdLineParser(mArgs);
    	    Assert.assertEquals(Level.INFO, parser.getLogLevel());
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}
	}
	
    @Test
    public void testSetLogLevel()
    {
    	// case 1: no level
    	try
    	{
    	    String[] args = {"--list",};
    	    CmdLineParser parser = new CmdLineParser(args);
    	    Assert.assertEquals(Level.OFF, parser.getLogLevel());
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}
    	
    	// case 2: verbose level
    	try
    	{
    	    String[] vArgs = {"--list", "-v"};
    	    CmdLineParser parser = new CmdLineParser(vArgs);
    	    Assert.assertEquals(Level.INFO, parser.getLogLevel());
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}
    	
    	// case 3: debug level
    	try
    	{
    	    String[] dArgs = {"--list", "-d"};
    	    CmdLineParser parser = new CmdLineParser(dArgs);
    	    Assert.assertEquals(Level.DEBUG, parser.getLogLevel());
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}
    	
    	// case 4: debug level
    	CmdLineParser parser = null;
    	
    	try
    	{
    	    String[] mArgs = {"--list", "-d", "-v"};
    	    parser = new CmdLineParser(mArgs);
    	    Assert.fail("Should have received a UsageException.");
    	}
    	catch (UsageException e)
    	{
    		String expected = "--verbose and --debug are mutually exclusive options";
    		Assert.assertTrue(e.getMessage().contains(expected));
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}
    	
    	Assert.assertNull(parser);
    }
    
    @Test
    public void testCommandValidation()
    {
    	// case 1: no command
    	try
    	{
    	    String[] dArgs = {"-d"};
    	    new CmdLineParser(dArgs);
    	    Assert.fail("Should have received a UsageException.");
    	}
    	catch (UsageException e)
    	{
    		String expected = "Missing command or ommand is not supported";
    		Assert.assertTrue(e.getMessage().contains(expected));
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}
    	
    	// case 2: one --list command
    	try
    	{
    	    String[] dArgs = {"--list", "-d"};
    	    CmdLineParser parser = new CmdLineParser(dArgs);
    	    Assert.assertEquals(Level.DEBUG, parser.getLogLevel());
    	    Assert.assertTrue(parser.getCommand() instanceof ListActiveUsers);
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}
    	
    	// case 3: one --list-pending command
    	try
    	{
    	    String[] dArgs = {"--list-pending", "-d"};
    	    CmdLineParser parser = new CmdLineParser(dArgs);
    	    Assert.assertEquals(Level.DEBUG, parser.getLogLevel());
    	    Assert.assertTrue(parser.getCommand() instanceof ListPendingUsers);
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}
    	
    	// case 4: one --view command
    	try
    	{
    	    String[] dArgs = {"--view=jdoe", "-d"};
    	    CmdLineParser parser = new CmdLineParser(dArgs);
    	    Assert.assertEquals(Level.DEBUG, parser.getLogLevel());
    	    Assert.assertTrue(parser.getCommand() instanceof ViewUser);
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}
    	
    	// case 5: one --reject command
    	try
    	{
    	    String[] dArgs = {"--reject=jdoe", "-d"};
    	    CmdLineParser parser = new CmdLineParser(dArgs);
    	    Assert.assertEquals(Level.DEBUG, parser.getLogLevel());
    	    Assert.assertTrue(parser.getCommand() instanceof RejectUser);
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}
    	
    	// case 6: one --approve command
    	try
    	{
    	    String[] dArgs = {"--approve=jdoe", "-d"};
    	    CmdLineParser parser = new CmdLineParser(dArgs);
    	    Assert.assertEquals(Level.DEBUG, parser.getLogLevel());
    	    Assert.assertTrue(parser.getCommand() instanceof ApproveUser);
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}
    	
    	// case 7: one command with no user ID
    	try
    	{
    	    String[] dArgs = {"--approve", "-d"};
    	    new CmdLineParser(dArgs);
    	    Assert.fail("Should have received a UsageException.");
    	}
    	catch (UsageException e)
    	{
    		String expected = "Missing userID";
    		Assert.assertTrue(e.getMessage().contains(expected));
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}
    	
    	// case 8: one command with no user ID
    	try
    	{
    	    String[] dArgs = {"--approve=", "-d"};
    	    new CmdLineParser(dArgs);
    	    Assert.fail("Should have received a UsageException.");
    	}
    	catch (UsageException e)
    	{
    		String expected = "Missing userID";
    		Assert.assertTrue(e.getMessage().contains(expected));
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}
    	
    	// case 8: more than one command
    	try
    	{
    	    String[] dArgs = {"--list", "--list-pending", "-d"};
    	    new CmdLineParser(dArgs);
    	    Assert.fail("Should have received a UsageException.");
    	}
    	catch (UsageException e)
    	{
    		String expected = "Only one command can be specified";
    		Assert.assertTrue(e.getMessage().contains(expected));
    	}
    	catch (Exception e)
    	{
    	    Assert.fail("Caught an unexpected exception, " + e.getMessage());
    	}

    }
}