Author: rmannibucau
Date: Wed Oct 24 09:31:44 2012
New Revision: 1401596

URL: http://svn.apache.org/viewvc?rev=1401596&view=rev
Log:
TOMEE-500 password cipher for tomcat-jdbc

Added:
    
openejb/trunk/openejb/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolCipherPasswordTest.java
      - copied, changed from r1401234, 
openejb/trunk/openejb/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolTest.java
    openejb/trunk/openejb/tomee/tomee-jdbc/src/test/resources/
    openejb/trunk/openejb/tomee/tomee-jdbc/src/test/resources/META-INF/
    
openejb/trunk/openejb/tomee/tomee-jdbc/src/test/resources/META-INF/org.apache.openejb.resource.jdbc.cipher.PasswordCipher/
    
openejb/trunk/openejb/tomee/tomee-jdbc/src/test/resources/META-INF/org.apache.openejb.resource.jdbc.cipher.PasswordCipher/Mock
Modified:
    openejb/trunk/openejb/rat.xml
    
openejb/trunk/openejb/tomee/tomee-jdbc/src/main/java/org/apache/tomee/jdbc/TomEEDataSourceCreator.java

Modified: openejb/trunk/openejb/rat.xml
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/rat.xml?rev=1401596&r1=1401595&r2=1401596&view=diff
==============================================================================
--- openejb/trunk/openejb/rat.xml (original)
+++ openejb/trunk/openejb/rat.xml Wed Oct 24 09:31:44 2012
@@ -74,6 +74,7 @@
           <exclude 
name="tomee/tomee-myfaces/src/main/resources/META-INF/services/org.apache.myfaces.spi.FacesConfigResourceProviderFactory"/>
           <exclude 
name="tomee/tomee-webapp/src/main/webapp/js/jquery/jquery-1.7.1.js"/>
           <exclude 
name="tomee/tomee-mojarra/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider"
 />
+          <exclude 
name="tomee/tomee-jdbc/src/test/resources/META-INF/org.apache.openejb.resource.jdbc.cipher.PasswordCipher/Mock"
 />
           <exclude 
name="tomee/tomee-webapp/src/main/webapp/lib/jquery/jquery-1.7.2.min.js" /> 
<!-- minimize so ignored -->
 
           <!-- user-owned config files.  see httpds default.httpd.conf for 
precident --> 

Modified: 
openejb/trunk/openejb/tomee/tomee-jdbc/src/main/java/org/apache/tomee/jdbc/TomEEDataSourceCreator.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-jdbc/src/main/java/org/apache/tomee/jdbc/TomEEDataSourceCreator.java?rev=1401596&r1=1401595&r2=1401596&view=diff
==============================================================================
--- 
openejb/trunk/openejb/tomee/tomee-jdbc/src/main/java/org/apache/tomee/jdbc/TomEEDataSourceCreator.java
 (original)
+++ 
openejb/trunk/openejb/tomee/tomee-jdbc/src/main/java/org/apache/tomee/jdbc/TomEEDataSourceCreator.java
 Wed Oct 24 09:31:44 2012
@@ -21,6 +21,7 @@ import org.apache.juli.logging.LogFactor
 import org.apache.openejb.monitoring.LocalMBeanServer;
 import org.apache.openejb.monitoring.ObjectNameBuilder;
 import org.apache.openejb.resource.jdbc.BasicDataSourceUtil;
+import org.apache.openejb.resource.jdbc.cipher.PasswordCipher;
 import org.apache.openejb.resource.jdbc.plugin.DataSourcePlugin;
 import org.apache.openejb.resource.jdbc.pool.PoolDataSourceCreator;
 import org.apache.openejb.util.Duration;
@@ -109,13 +110,31 @@ public class TomEEDataSourceCreator exte
         if (properties.containsKey("minEvictableIdleTime") && 
!properties.containsKey("minEvictableIdleTimeMillis")) {
             converted.setProperty("minEvictableIdleTimeMillis", minEvict);
         }
+
+        final String passwordCipher = properties.getProperty("PasswordCipher");
+        if (passwordCipher != null && "PlainText".equals(passwordCipher)) { // 
no need to warn about it
+            properties.remove("PasswordCipher");
+        } else {
+            String password = properties.getProperty("Password");
+            if (passwordCipher != null) {
+                try {
+                    final PasswordCipher cipher = 
BasicDataSourceUtil.getPasswordCipher(passwordCipher);
+                    final String plainPwd = 
cipher.decrypt(password.toCharArray());
+                    converted.setProperty("password", plainPwd);
+
+                    // all went fine so remove it to avoid errors later
+                    properties.remove("PasswordCipher");
+                    properties.remove("Password");
+                } catch (SQLException e) {
+                    LOGGER.error("Can't decrypt password", e);
+                }
+            }
+        }
+
         for (Map.Entry<Object, Object> entry : properties.entrySet()) {
             final String key = entry.getKey().toString();
             final String value = entry.getValue().toString().trim();
             if (!value.isEmpty() && !converted.containsKey(key)) {
-                if ("PasswordCipher".equals(key) && "PlainText".equals(value)) 
{ // no need to warn about it
-                    continue;
-                }
                 if ("MaxOpenPreparedStatements".equalsIgnoreCase(key) || 
"PoolPreparedStatements".equalsIgnoreCase(key)) {
                     String interceptors = 
properties.getProperty("jdbcInterceptors");
                     if (interceptors == null || 
!interceptors.contains("StatementCache")) {
@@ -164,15 +183,26 @@ public class TomEEDataSourceCreator exte
 
     public static class TomEEDataSource extends 
org.apache.tomcat.jdbc.pool.DataSource {
         private static final Log LOGGER = 
LogFactory.getLog(TomEEDataSource.class);
+        private static final Class<?>[] CONNECTION_POOL_CLASS = new Class<?>[] 
{ PoolConfiguration.class };
 
         private ObjectName internalOn = null;
 
         public TomEEDataSource(final PoolConfiguration properties, final 
ConnectionPool pool, final String name) {
-            super(properties);
+            super(readOnly(properties));
             this.pool = pool;
             initJmx(name);
         }
 
+        public TomEEDataSource(final PoolConfiguration poolConfiguration, 
final String name) {
+            super(readOnly(poolConfiguration));
+            try { // just to force the pool to be created and be able to 
register the mbean
+                createPool();
+                initJmx(name);
+            } catch (Throwable ignored) {
+                // no-op
+            }
+        }
+
         @Override
         public ConnectionPool createPool() throws SQLException {
             if (pool != null) {
@@ -183,14 +213,8 @@ public class TomEEDataSourceCreator exte
             }
         }
 
-        public TomEEDataSource(final PoolConfiguration poolConfiguration, 
final String name) {
-            super(poolConfiguration);
-            try { // just to force the pool to be created and be able to 
register the mbean
-                createPool();
-                initJmx(name);
-            } catch (Throwable ignored) {
-                // no-op
-            }
+        private static PoolConfiguration readOnly(final PoolConfiguration 
pool) {
+            return (PoolConfiguration) 
Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), 
CONNECTION_POOL_CLASS, new ReadOnlyConnectionpool(pool));
         }
 
         private void initJmx(final String name) {
@@ -233,6 +257,22 @@ public class TomEEDataSourceCreator exte
         }
     }
 
+    private static class ReadOnlyConnectionpool implements InvocationHandler {
+        private final PoolConfiguration delegate;
+
+        public ReadOnlyConnectionpool(final PoolConfiguration pool) {
+            delegate = pool;
+        }
+
+        @Override
+        public Object invoke(final Object proxy, final Method method, final 
Object[] args) throws Throwable {
+            if (!(method.getName().startsWith("set") && args != null && 
args.length == 1 && Void.TYPE.equals(method.getReturnType()))) {
+                return method.invoke(delegate, args);
+            }
+            return null;
+        }
+    }
+
     private static class TomEEConnectionPool extends ConnectionPool {
         public TomEEConnectionPool(final PoolConfiguration poolProperties) 
throws SQLException {
             super(poolProperties);

Copied: 
openejb/trunk/openejb/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolCipherPasswordTest.java
 (from r1401234, 
openejb/trunk/openejb/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolTest.java)
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolCipherPasswordTest.java?p2=openejb/trunk/openejb/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolCipherPasswordTest.java&p1=openejb/trunk/openejb/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolTest.java&r1=1401234&r2=1401596&rev=1401596&view=diff
==============================================================================
--- 
openejb/trunk/openejb/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolTest.java
 (original)
+++ 
openejb/trunk/openejb/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolCipherPasswordTest.java
 Wed Oct 24 09:31:44 2012
@@ -17,46 +17,47 @@
 package org.apache.tomee.jdbc;
 
 import org.apache.openejb.jee.EjbJar;
-import org.apache.openejb.jee.SingletonBean;
 import org.apache.openejb.junit.ApplicationComposer;
 import org.apache.openejb.junit.Configuration;
 import org.apache.openejb.junit.Module;
-import org.apache.openejb.resource.jdbc.managed.local.ManagedConnection;
-import org.junit.After;
+import org.apache.openejb.resource.jdbc.cipher.PasswordCipher;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import javax.annotation.Resource;
-import javax.ejb.EJB;
-import javax.ejb.EJBContext;
-import javax.ejb.LocalBean;
-import javax.ejb.Singleton;
-import javax.ejb.TransactionAttribute;
-import javax.ejb.TransactionAttributeType;
 import javax.sql.DataSource;
-import java.lang.reflect.Field;
 import java.sql.Connection;
 import java.sql.DriverManager;
-import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
-import java.util.Map;
 import java.util.Properties;
 
+import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertThat;
 
 @RunWith(ApplicationComposer.class)
-public class TomcatPoolTest {
-    private static final String URL = 
"jdbc:hsqldb:mem:managed;hsqldb.tx=MVCC"; // mvcc otherwise multiple 
transaction tests will fail
+public class TomcatPoolCipherPasswordTest {
+    private static final String URL = "jdbc:hsqldb:mem:cipher;hsqldb.tx=MVCC";
     private static final String USER = "sa";
-    private static final String PASSWORD = "";
+    private static final String PASSWORD = "this one will be overriden if it 
works";
     private static final String TABLE = "PUBLIC.MANAGED_DATASOURCE_TEST";
 
-    @EJB
-    private Persister persistManager;
+    @Resource(name = "ciphered")
+    private DataSource ds;
+
+    public static class MockCipher implements PasswordCipher {
+        @Override
+        public char[] encrypt(final String plainPassword) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String decrypt(final char[] encryptedPassword) {
+            return "";
+        }
+    }
 
     @BeforeClass
     public static void createTable() throws SQLException, 
ClassNotFoundException {
@@ -75,157 +76,26 @@ public class TomcatPoolTest {
         final Properties p = new Properties();
         p.put("openejb.jdbc.datasource-creator", 
TomEEDataSourceCreator.class.getName());
 
-        p.put("managed", "new://Resource?type=DataSource");
-        p.put("managed.JdbcDriver", "org.hsqldb.jdbcDriver");
-        p.put("managed.JdbcUrl", URL);
-        p.put("managed.UserName", USER);
-        p.put("managed.Password", PASSWORD);
-        p.put("managed.JtaManaged", "true");
-        p.put("managed.JdbcInterceptors", "StatementCache(prepared=true)");
+        p.put("ciphered", "new://Resource?type=DataSource");
+        p.put("ciphered.JdbcDriver", "org.hsqldb.jdbcDriver");
+        p.put("ciphered.JdbcUrl", URL);
+        p.put("ciphered.UserName", USER);
+        p.put("ciphered.Password", PASSWORD);
+        p.put("ciphered.PasswordCipher", "Mock");
+        p.put("ciphered.JtaManaged", "false");
+        p.put("ciphered.JdbcInterceptors", "StatementCache(prepared=true)");
         return p;
     }
 
     @Module
     public EjbJar app() throws Exception {
-        return new EjbJar()
-                .enterpriseBean(new SingletonBean(Persister.class).localBean())
-                .enterpriseBean(new 
SingletonBean(OtherPersister.class).localBean());
-    }
-
-    @LocalBean
-    @Singleton
-    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
-    public static class OtherPersister {
-        @Resource(name = "managed")
-        private DataSource ds;
-
-        @Resource
-        private EJBContext context;
-
-        public void save() throws SQLException {
-            TomcatPoolTest.save(ds, 10);
-        }
-
-        public void saveAndRollback() throws SQLException {
-            TomcatPoolTest.save(ds, 11);
-            context.setRollbackOnly();
-        }
-    }
-
-    @LocalBean
-    @Singleton
-    public static class Persister {
-        @Resource(name = "managed")
-        private DataSource ds;
-
-        @Resource
-        private EJBContext context;
-
-        @EJB
-        private OtherPersister other;
-
-        public void save() throws SQLException {
-            TomcatPoolTest.save(ds, 1);
-        }
-
-        public void saveAndRollback() throws SQLException {
-            TomcatPoolTest.save(ds, 2);
-            context.setRollbackOnly();
-        }
-
-        public void saveTwice() throws SQLException {
-            TomcatPoolTest.save(ds, 3);
-            TomcatPoolTest.save(ds, 4);
-        }
-
-        public void rollbackMultipleSave() throws SQLException {
-            TomcatPoolTest.save(ds, 5);
-            TomcatPoolTest.save(ds, 6);
-            context.setRollbackOnly();
-        }
-
-        public void saveInThisTxAndAnotherOne() throws SQLException {
-            TomcatPoolTest.save(ds, 7);
-            other.save();
-        }
-
-        public void saveInThisTxAndRollbackInAnotherOne() throws SQLException {
-            TomcatPoolTest.save(ds, 8);
-            other.saveAndRollback();
-        }
+        return new EjbJar();
     }
 
     @Test
-    public void commit() throws SQLException {
-        persistManager.save();
-        assertTrue(exists(1));
-    }
-
-    @Test
-    public void rollback() throws SQLException {
-        persistManager.saveAndRollback();
-        assertFalse(exists(2));
-    }
-
-    @Test
-    public void commit2() throws SQLException {
-        persistManager.saveTwice();
-        assertTrue(exists(3));
-        assertTrue(exists(4));
-    }
-
-    @Test
-    public void rollback2() throws SQLException {
-        persistManager.rollbackMultipleSave();
-        assertFalse(exists(5));
-        assertFalse(exists(6));
-    }
-
-    @Test
-    public void saveDifferentTx() throws SQLException {
-        persistManager.saveInThisTxAndAnotherOne();
-        assertTrue(exists(7));
-        assertTrue(exists(10));
-    }
-
-    @Test
-    public void saveRollbackDifferentTx() throws SQLException {
-        persistManager.saveInThisTxAndRollbackInAnotherOne();
-        assertTrue(exists(8));
-        assertFalse(exists(12));
-    }
-
-    @After
-    public void checkTxMapIsEmpty() throws Exception { // avoid memory leak
-        final Field map = 
ManagedConnection.class.getDeclaredField("CONNECTION_BY_TX");
-        map.setAccessible(true);
-        final Map<?, ?> instance = (Map<?, ?>) map.get(null);
-        assertEquals(0, instance.size());
-    }
-
-    private static boolean exists(int id) throws SQLException {
-        final Connection connection = DriverManager.getConnection(URL, USER, 
PASSWORD);
-        final Statement statement = connection.createStatement();
-        final ResultSet result = statement.executeQuery("SELECT count(*) AS NB 
FROM " + TABLE + " WHERE ID = " + id);
-        try {
-            assertTrue(result.next());
-            return result.getInt(1) == 1;
-        } finally {
-            statement.close();
-            connection.close();
-        }
-    }
-
-    private static void save(final DataSource ds, int id) throws SQLException {
-        execute(ds, "INSERT INTO " + TABLE + "(ID) VALUES(" + id + ")");
-    }
-
-    private static void execute(final DataSource ds, final String sql) throws 
SQLException {
-        final Connection connection = ds.getConnection();
-        final Statement statement = connection.createStatement();
-        statement.executeUpdate(sql);
-        statement.close();
-        connection.close();
+    public void validConfig() throws SQLException {
+        assertThat(ds, 
instanceOf(TomEEDataSourceCreator.TomEEDataSource.class));
+        assertEquals(new MockCipher().decrypt(null), 
((TomEEDataSourceCreator.TomEEDataSource) 
ds).getPoolProperties().getPassword());
     }
 }
 

Added: 
openejb/trunk/openejb/tomee/tomee-jdbc/src/test/resources/META-INF/org.apache.openejb.resource.jdbc.cipher.PasswordCipher/Mock
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-jdbc/src/test/resources/META-INF/org.apache.openejb.resource.jdbc.cipher.PasswordCipher/Mock?rev=1401596&view=auto
==============================================================================
--- 
openejb/trunk/openejb/tomee/tomee-jdbc/src/test/resources/META-INF/org.apache.openejb.resource.jdbc.cipher.PasswordCipher/Mock
 (added)
+++ 
openejb/trunk/openejb/tomee/tomee-jdbc/src/test/resources/META-INF/org.apache.openejb.resource.jdbc.cipher.PasswordCipher/Mock
 Wed Oct 24 09:31:44 2012
@@ -0,0 +1 @@
+org.apache.tomee.jdbc.TomcatPoolCipherPasswordTest$MockCipher


Reply via email to