/**
* VMware Continuent Tungsten Replicator
* Copyright (C) 2015 VMware, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Initial developer(s): Ludovic Launer
*/
package com.continuent.tungsten.common.security;
import junit.framework.TestCase;
import com.continuent.tungsten.common.config.TungstenProperties;
import com.continuent.tungsten.common.config.cluster.ConfigurationException;
import com.continuent.tungsten.common.jmx.ServerRuntimeException;
import com.continuent.tungsten.common.security.PasswordManager.ClientApplicationType;
/**
* Implements a simple unit test for AuthenticationInfo
*
* @author <a href="mailto:ludovic.launer@continuent.com">Ludovic Launer</a>
* @version 1.0
*/
public class PasswordManagerTest extends TestCase
{
/**
* Confirm that we can create an instance of PasswordManager with a non
* existing security.proprties.
* The exception is raised once we do a check on the AuthenticationInfo
* Create an instance of a PasswordManager reading from a
* security.properties file
*
* @throws ConfigurationException
*/
public void testCreatePasswordManager() throws ConfigurationException
{
// This file should load just fine
PasswordManager pwd = new PasswordManager("sample.security.properties");
assertTrue(true);
// This one should load fine too
try
{
pwd = new PasswordManager(
"sample.security.properties_DOES_NOT_EXIST");
AuthenticationInfo authenticationInfo = pwd.getAuthenticationInfo();
authenticationInfo.checkAndCleanAuthenticationInfo();
}
catch (ConfigurationException e)
{
assertTrue(false);
}
catch (ServerRuntimeException sre)
{
// That's the expected exception from checkAuthenticationInfo();
assertTrue(true);
}
}
/**
* Test loading passwords from a file
* Should succeed with correct password file location
* Should throw an Exception if the password file location is not correct
*
* @throws ConfigurationException
*/
public void testloadPasswordsAsTungstenProperties()
throws ConfigurationException
{
// --- Load passwords from existing file ---
// This file should load just fine
PasswordManager pwd = new PasswordManager("sample.security.properties");
// List of passwords is popualted once we have loaded it
TungstenProperties passwdProps = pwd
.loadPasswordsAsTungstenProperties();
assertEquals(true, passwdProps.size() != 0);
// And we can retrieve a password for an existing user
String goodPassword = passwdProps.get("tungsten");
assertNotNull(goodPassword);
// --- Load passwords from a non existing file ---
// We modify the password file location so that it does not exist
AuthenticationInfo authInfo = pwd.getAuthenticationInfo();
authInfo.setPasswordFileLocation(authInfo.getPasswordFileLocation()
+ "_DOES_NOT_EXIST");
// We should now have an exception when trying to get passwords
try
{
passwdProps = pwd.loadPasswordsAsTungstenProperties();
assertTrue(false);
}
catch (ServerRuntimeException e)
{
assertTrue(true);
}
}
/**
* Test retrieving passwords from file.
* Passwords are returned in clear text even if they were encoded
* Decryption is done in the AuthenticationInfo class
*
* @throws ConfigurationException
*/
public void testgetPasswordForUser() throws ConfigurationException
{
PasswordManager pwd = null;
String goodPassword = null;
try
{
pwd = new PasswordManager("sample.security.properties");
}
catch (ConfigurationException e)
{
assertTrue(false);
}
// Try to get password without having loaded the passwords
goodPassword = pwd.getClearTextPasswordForUser("tungsten");
assertNotNull(goodPassword);
// Get a password for a non existing user
goodPassword = pwd.getClearTextPasswordForUser("non_existing_user");
assertNull(goodPassword);
}
/**
* Test retrieving passwords from file : Application Specific
* Passwords are returned in clear text even if they were encoded
* Decryption is done in the AuthenticationInfo class
* Gets application specific user
*
* @throws ConfigurationException
*/
public void testgetPasswordForUser_by_Application()
throws ConfigurationException
{
PasswordManager pwd = null;
String goodPassword = null;
String goodEncryptedPassword = null;
try
{
pwd = new PasswordManager("sample.security.properties",
ClientApplicationType.RMI_JMX);
}
catch (ConfigurationException e)
{
assertTrue(false);
}
// Try to get password without having loaded the passwords
goodEncryptedPassword = pwd.getEncryptedPasswordForUser("tungsten");
goodPassword = pwd.getClearTextPasswordForUser("tungsten");
assertNotNull(goodEncryptedPassword); // We should get something
assertNotNull(goodPassword);
assertTrue(goodEncryptedPassword != goodPassword); // Clear text and
// encyprted password
// should be
// different
assertEquals("secret", goodPassword); // The expected clear text
// password = secret
// Get a password for a non existing user
goodPassword = pwd.getClearTextPasswordForUser("non_existing_user");
assertNull(goodPassword);
}
/**
* Confirm that we can authenticate (or not) a user.
*
* @throws ConfigurationException
*/
public void testAuthenticateUser() throws ConfigurationException
{
PasswordManager pwd = null;
try
{
pwd = new PasswordManager("sample.security.properties",
ClientApplicationType.RMI_JMX);
}
catch (ConfigurationException e)
{
assertTrue(false);
}
// Try to authenticate the user
boolean authOK = pwd.authenticateUser("tungsten", "secret");
assertTrue(authOK);
// Try with a wrong password
authOK = pwd.authenticateUser("tungsten", "wrong_password");
assertFalse(authOK);
// Try with a non existing user
try
{
authOK = pwd
.authenticateUser("non_existing_user", "wrong_password");
assertTrue(
"Try with a non existing user: call should have raised an exception",
false);
}
catch (ServerRuntimeException sre)
{
assertTrue(true);
}
}
/**
* Test creating / updating / deleting passwords from file
*
* @throws ConfigurationException
*/
public void testSavePasswordForUser_by_Application()
throws ConfigurationException
{
PasswordManager pwd = new PasswordManager("sample.security.properties",
ClientApplicationType.RMI_JMX);
// -- Try to create a new username=password
String username = "ludovic";
String password = "ludovic_password";
String new_password = "my_new_password";
try
{
pwd.setPasswordForUser(username, password);
}
catch (Exception e)
{
assertTrue(false); // Password saved without any Exception
}
// --- Try to retrieve what we've just stored ---
pwd = new PasswordManager("sample.security.properties",
ClientApplicationType.RMI_JMX);
String retrievePassword = pwd.getClearTextPasswordForUser(username);
assertEquals(password, retrievePassword);
// --- Try to update exising password ---
pwd.setPasswordForUser(username, new_password);
// --- Again, try to retrieve the new password ---
pwd = new PasswordManager("sample.security.properties",
ClientApplicationType.RMI_JMX);
retrievePassword = pwd.getClearTextPasswordForUser(username);
assertEquals(new_password, retrievePassword);
// ##### Backward compatibility ###
// --- Retrieve the list of passwords using standard TungstenProperties
// ---
// This tests the backward compatibility with the TungstenProperties
// reader. Apache adds a space after the key and before the value: key =
// value
pwd = new PasswordManager("sample.security.properties",
ClientApplicationType.RMI_JMX);
// List of passwords is popualted once we have loaded it
TungstenProperties passwdProps = pwd
.loadPasswordsAsTungstenProperties();
assertEquals(true, passwdProps.size() != 0);
// And we can retrieve a password for an existing user
String goodPassword = passwdProps.get(pwd
.getApplicationSpecificUsername(username));
assertNotNull(goodPassword);
// ################################
// --- Try to delete a non existing user ---
try
{
pwd.deleteUser("non_existing_user");
assertTrue(false); // We should not get there as there should be an
// exception raised
}
catch (Exception e)
{
assertTrue(true); // An exception was raised: that's fine
}
// --- Try to delete the created user ---
try
{
pwd.deleteUser("ludovic");
}
catch (Exception e)
{
assertTrue(false); // Password saved without any Exception
}
// --- Check that the user does not exist anymore ---
pwd = new PasswordManager("sample.security.properties",
ClientApplicationType.RMI_JMX);
retrievePassword = pwd.getClearTextPasswordForUser("ludovic");
assertNull(retrievePassword); // The user should not be there anymore
}
}