tomee-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dblev...@apache.org
Subject svn commit: r703061 - in /openejb/trunk/openejb3/container/openejb-core/src: main/java/org/apache/openejb/core/security/jaas/ main/java/org/apache/openejb/util/ main/resources/ test/java/org/apache/openejb/core/security/ test/java/org/apache/openejb/co...
Date Thu, 09 Oct 2008 05:25:52 GMT
Author: dblevins
Date: Wed Oct  8 22:25:52 2008
New Revision: 703061

URL: http://svn.apache.org/viewvc?rev=703061&view=rev
Log:
OPENEJB-920: JDBC/DataSource based login module
Patch from Alex Grönholm based on the Geronimo SQLLoginModule.  Thanks, Alex!

Added:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/jaas/SQLLoginModule.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/HexConverter.java
    openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/security/SQLLoginModuleTest.java
    openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/HexConverterTest.java
Modified:
    openejb/trunk/openejb3/container/openejb-core/src/main/resources/login.config
    openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/StatelessContainerTest.java

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/jaas/SQLLoginModule.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/jaas/SQLLoginModule.java?rev=703061&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/jaas/SQLLoginModule.java
(added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/jaas/SQLLoginModule.java
Wed Oct  8 22:25:52 2008
@@ -0,0 +1,420 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.
+ */
+
+package org.apache.openejb.core.security.jaas;
+
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.spi.ContainerSystem;
+import org.apache.openejb.util.Base64;
+import org.apache.openejb.util.HexConverter;
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
+import org.apache.openejb.util.StringUtilities;
+
+import javax.naming.NamingException;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.FailedLoginException;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+import javax.sql.DataSource;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.EnumMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+/**
+ * A login module that loads security information from a SQL database.  Expects
+ * to be run by a GenericSecurityRealm (doesn't work on its own).
+ * <p/>
+ * This requires database connectivity information (either 1: a dataSourceName and
+ * optional dataSourceApplication or 2: a JDBC driver, URL, username, and password)
+ * and 2 SQL queries.
+ * <p/>
+ * The userSelect query should return 2 values, the username and the password in
+ * that order.  It should include one PreparedStatement parameter (a ?) which
+ * will be filled in with the username.  In other words, the query should look
+ * like: <tt>SELECT user, password FROM credentials WHERE username=?</tt>
+ * <p/>
+ * The groupSelect query should return 2 values, the username and the group name in
+ * that order (but it may return multiple rows, one per group).  It should include
+ * one PreparedStatement parameter (a ?) which will be filled in with the username.
+ * In other words, the query should look like:
+ * <tt>SELECT user, role FROM user_roles WHERE username=?</tt>
+ * <p/>
+ * This login module checks security credentials so the lifecycle methods must return true
to indicate success
+ * or throw LoginException to indicate failure.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SQLLoginModule implements LoginModule {
+    private static Logger log = Logger.getInstance(
+            LogCategory.OPENEJB_SECURITY, "org.apache.openejb.util.resources");
+
+    private EnumMap<Option, String> optionsMap = new EnumMap<Option, String>(Option.class);
+    private String connectionURL;
+    private Properties properties;
+    private Driver driver;
+    private DataSource dataSource;
+    private String userSelect;
+    private String groupSelect;
+    private String digest;
+    private String encoding;
+
+    private boolean loginSucceeded;
+    private Subject subject;
+    private CallbackHandler handler;
+    private String cbUsername;
+    private String cbPassword;
+    private final Set<String> groups = new HashSet<String>();
+    private final Set<Principal> allPrincipals = new HashSet<Principal>();
+
+    public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState,
Map options) {
+        this.subject = subject;
+        this.handler = callbackHandler;
+
+        for (Object key : options.keySet()) {
+            Option option = Option.findByName((String) key);
+            if (option != null) {
+                String value = (String) options.get(key);
+                optionsMap.put(option, value.trim());
+            } else {
+                log.warning("Ignoring option: {0}. Not supported.", key);
+            }
+        }
+
+        userSelect = optionsMap.get(Option.USER_SELECT);
+        groupSelect = optionsMap.get(Option.GROUP_SELECT);
+
+        digest = optionsMap.get(Option.DIGEST);
+        encoding = optionsMap.get(Option.ENCODING);
+
+        if (!StringUtilities.checkNullBlankString(digest)) {
+            // Check if the digest algorithm is available
+            try {
+                MessageDigest.getInstance(digest);
+            } catch (NoSuchAlgorithmException e) {
+                initError(e, "Digest algorithm %s is not available.", digest);
+            }
+
+            if (encoding != null && !"hex".equalsIgnoreCase(encoding) &&
!"base64".equalsIgnoreCase(encoding)) {
+                initError(null, "Digest Encoding %s is not supported.", encoding);
+            }
+        }
+
+        if (optionsMap.containsKey(Option.DATABASE_POOL_NAME)) {
+            String dataSourceName = optionsMap.get(Option.DATABASE_POOL_NAME);
+            ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
+            try {
+                dataSource = (DataSource) containerSystem.getJNDIContext().lookup("openejb/Resource/"
+ dataSourceName);
+            } catch (NamingException e) {
+                initError(e, "Data source %s not found.", dataSourceName);
+            }
+        } else if (optionsMap.containsKey(Option.CONNECTION_URL)) {
+            connectionURL = optionsMap.get(Option.CONNECTION_URL);
+            String user = optionsMap.get(Option.USER);
+            String password = optionsMap.get(Option.PASSWORD);
+            String driverName = optionsMap.get(Option.DRIVER);
+            properties = new Properties();
+
+            if (user != null) {
+                properties.put("user", user);
+            }
+
+            if (password != null) {
+                properties.put("password", password);
+            }
+
+            if (driverName != null) {
+                ClassLoader cl = getClass().getClassLoader();
+                try {
+                    driver = (Driver) cl.loadClass(driverName).newInstance();
+                } catch (ClassNotFoundException e) {
+                    initError(e, "Driver class %s is not available. Perhaps you need to add
it as a dependency in your deployment plan?", driverName);
+                } catch (Exception e) {
+                    initError(e, "Unable to load, instantiate, register driver %s: %s", driverName,
e.getMessage());
+                }
+            }
+        } else {
+            initError(null, "Neither %s nor %s was specified", Option.DATABASE_POOL_NAME.name,
Option.CONNECTION_URL.name);
+        }
+    }
+
+    private void initError(Exception e, String format, Object... args) {
+        String message = String.format(format, args);
+        log.error("Initialization failed. {0}", message);
+        throw new IllegalArgumentException(message, e);
+    }
+
+    /**
+     * This LoginModule is not to be ignored. So, this method should never
+     * return false.
+     *
+     * @return true if authentication succeeds, or throw a LoginException such
+     *         as FailedLoginException if authentication fails
+     */
+    public boolean login() throws LoginException {
+        loginSucceeded = false;
+        Callback[] callbacks = new Callback[2];
+
+        callbacks[0] = new NameCallback("User name");
+        callbacks[1] = new PasswordCallback("Password", false);
+
+        try {
+            handler.handle(callbacks);
+        } catch (IOException ioe) {
+            throw (LoginException) new LoginException().initCause(ioe);
+        } catch (UnsupportedCallbackException uce) {
+            throw (LoginException) new LoginException().initCause(uce);
+        }
+
+        assert callbacks.length == 2;
+
+        cbUsername = ((NameCallback) callbacks[0]).getName();
+
+        if (StringUtilities.checkNullBlankString(cbUsername)) {
+            throw new FailedLoginException();
+        }
+
+        char[] provided = ((PasswordCallback) callbacks[1]).getPassword();
+        cbPassword = provided == null ? null : new String(provided);
+
+        try {
+            Connection conn;
+            if (dataSource != null) {
+                conn = dataSource.getConnection();
+            } else if (driver != null) {
+                conn = driver.connect(connectionURL, properties);
+            } else {
+                conn = DriverManager.getConnection(connectionURL, properties);
+            }
+
+            try {
+                PreparedStatement statement = conn.prepareStatement(userSelect);
+                try {
+                    int count = statement.getParameterMetaData().getParameterCount();
+                    for (int i = 0; i < count; i++) {
+                        statement.setObject(i + 1, cbUsername);
+                    }
+                    ResultSet result = statement.executeQuery();
+
+                    try {
+                        boolean found = false;
+                        while (result.next()) {
+                            String userName = result.getString(1);
+                            String userPassword = result.getString(2);
+
+                            if (cbUsername.equals(userName)) {
+                                found = true;
+                                if (!checkPassword(userPassword, cbPassword)) {
+                                    throw new FailedLoginException();
+                                }
+                                break;
+                            }
+                        }
+                        if (!found) {
+                            // User does not exist
+                            throw new FailedLoginException();
+                        }
+                    } finally {
+                        result.close();
+                    }
+                } finally {
+                    statement.close();
+                }
+
+                statement = conn.prepareStatement(groupSelect);
+                try {
+                    int count = statement.getParameterMetaData().getParameterCount();
+                    for (int i = 0; i < count; i++) {
+                        statement.setObject(i + 1, cbUsername);
+                    }
+                    ResultSet result = statement.executeQuery();
+
+                    try {
+                        while (result.next()) {
+                            String userName = result.getString(1);
+                            String groupName = result.getString(2);
+
+                            if (cbUsername.equals(userName)) {
+                                groups.add(groupName);
+                            }
+                        }
+                    } finally {
+                        result.close();
+                    }
+                } finally {
+                    statement.close();
+                }
+            } finally {
+                conn.close();
+            }
+        } catch (LoginException e) {
+            // Clear out the private state
+            cbUsername = null;
+            cbPassword = null;
+            groups.clear();
+            throw e;
+        } catch (SQLException sqle) {
+            // Clear out the private state
+            cbUsername = null;
+            cbPassword = null;
+            groups.clear();
+            throw (LoginException) new LoginException("SQL error").initCause(sqle);
+        } catch (Exception e) {
+            // Clear out the private state
+            cbUsername = null;
+            cbPassword = null;
+            groups.clear();
+            throw (LoginException) new LoginException("Could not access datasource").initCause(e);
+        }
+
+        loginSucceeded = true;
+        return true;
+    }
+
+    /**
+     * @return true if login succeeded and commit succeeded, or false if login
+     *         failed but commit succeeded.
+     * @throws LoginException if login succeeded but commit failed.
+     */
+    public boolean commit() throws LoginException {
+        if (loginSucceeded) {
+            if (cbUsername != null) {
+                allPrincipals.add(new UserPrincipal(cbUsername));
+            }
+            for (String group : groups) {
+                allPrincipals.add(new GroupPrincipal(group));
+            }
+            subject.getPrincipals().addAll(allPrincipals);
+        }
+
+        // Clear out the private state
+        cbUsername = null;
+        cbPassword = null;
+        groups.clear();
+
+        return loginSucceeded;
+    }
+
+    public boolean abort() throws LoginException {
+        if (loginSucceeded) {
+            // Clear out the private state
+            cbUsername = null;
+            cbPassword = null;
+            groups.clear();
+            allPrincipals.clear();
+        }
+        return loginSucceeded;
+    }
+
+    public boolean logout() throws LoginException {
+        // Clear out the private state
+        loginSucceeded = false;
+        cbUsername = null;
+        cbPassword = null;
+        groups.clear();
+        if (!subject.isReadOnly()) {
+            // Remove principals added by this LoginModule
+            subject.getPrincipals().removeAll(allPrincipals);
+        }
+        allPrincipals.clear();
+        return true;
+    }
+
+    /**
+     * This method checks if the provided password is correct. The original
+     * password may have been digested.
+     *
+     * @param real     Original password in digested form if applicable
+     * @param provided User provided password in clear text
+     * @return true If the password is correct
+     */
+    private boolean checkPassword(String real, String provided) {
+        if (real == null && provided == null) {
+            return true;
+        }
+
+        if (real == null || provided == null) {
+            return false;
+        }
+
+        // Both are non-null
+        if (StringUtilities.checkNullBlankString(digest)) {
+            // No digest algorithm is used
+            return real.equals(provided);
+        }
+
+        try {
+            // Digest the user provided password
+            MessageDigest md = MessageDigest.getInstance(digest);
+            byte[] data = md.digest(provided.getBytes());
+
+            if (encoding == null || "hex".equalsIgnoreCase(encoding)) {
+                return real.equalsIgnoreCase(HexConverter.bytesToHex(data));
+            } else if ("base64".equalsIgnoreCase(encoding)) {
+                return real.equals(new String(Base64.encodeBase64(data)));
+            }
+        } catch (NoSuchAlgorithmException e) {
+            // Should not occur.  Availability of algorithm has been checked at initialization
+            log.error("Should not occur.  Availability of algorithm has been checked at initialization.",
e);
+        }
+        return false;
+    }
+
+    private enum Option {
+        USER_SELECT("userSelect"),
+        GROUP_SELECT("groupSelect"),
+        CONNECTION_URL("jdbcURL"),
+        USER("jdbcUser"),
+        PASSWORD("jdbcPassword"),
+        DRIVER("jdbcDriver"),
+        DATABASE_POOL_NAME("dataSourceName"),
+        DIGEST("digest"),
+        ENCODING("encoding");
+
+        public final String name;
+
+        private Option(String name) {
+            this.name = name;
+        }
+
+        public static Option findByName(String name) {
+            for (Option opt : values()) {
+                if (opt.name.equals(name))
+                    return opt;
+            }
+            return null;
+        }
+
+    }
+}
\ No newline at end of file

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/HexConverter.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/HexConverter.java?rev=703061&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/HexConverter.java
(added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/HexConverter.java
Wed Oct  8 22:25:52 2008
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.openejb.util;
+
+public class HexConverter {
+
+    private HexConverter() {
+        // Disallow instantiation
+    }
+
+    /**
+     * Converts a byte array to its hexadecimal string representation, ie.
+     * new byte[] { 127, 0, 10 } returns "7F000A".
+     *
+     * @param bytes an array of bytes
+     * @return hexadecimal string representation of the first argument
+     */
+    public static String bytesToHex(byte[] bytes) {
+        StringBuilder buf = new StringBuilder(bytes.length * 2);
+        for (byte b : bytes) {
+            buf.append(String.format("%02X", b));
+        }
+        return buf.toString();
+    }
+
+    /**
+     * Converts a hexadecimal formatted string into a corresponding byte array.
+     *
+     * @param hexString a hexadecimal representation of a byte array
+     * @return an array of bytes created from the input
+     */
+    public static byte[] hexToBytes(String hexString) {
+        if (hexString.length() % 2 != 0) {
+            throw new IllegalArgumentException("Invalid number of digits: input must be a
string of hexadecimal digit pairs");
+        }
+
+        byte[] bytes = new byte[hexString.length() / 2];
+        for (int i = 0; i < bytes.length; i++) {
+            bytes[i] = (byte) Integer.parseInt(hexString.substring(i * 2, i * 2 + 2), 16);
+        }
+        return bytes;
+    }
+
+}

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/resources/login.config
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/resources/login.config?rev=703061&r1=703060&r2=703061&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/resources/login.config (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/resources/login.config Wed Oct
 8 22:25:52 2008
@@ -4,3 +4,9 @@
         UsersFile="users.properties"
         GroupsFile="groups.properties";
 };
+SQLLogin {
+    org.apache.openejb.core.security.jaas.SQLLoginModule required
+    	jdbcURL="jdbc:hsqldb:mem:sqltest"
+    	userSelect="SELECT user, password FROM users WHERE user = ?"
+    	groupSelect="SELECT user, grp FROM groups WHERE user = ?";
+};
\ No newline at end of file

Added: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/security/SQLLoginModuleTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/security/SQLLoginModuleTest.java?rev=703061&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/security/SQLLoginModuleTest.java
(added)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/security/SQLLoginModuleTest.java
Wed Oct  8 22:25:52 2008
@@ -0,0 +1,141 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.openejb.core.security;
+
+import static junit.framework.Assert.assertEquals;
+
+import java.net.URL;
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.FailedLoginException;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+import org.apache.openejb.core.security.jaas.GroupPrincipal;
+import org.apache.openejb.core.security.jaas.UserPrincipal;
+import org.apache.openejb.core.security.jaas.UsernamePasswordCallbackHandler;
+import org.apache.openejb.util.URLs;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class SQLLoginModuleTest {
+
+	private static Connection conn;
+	
+	@BeforeClass
+    public static void setUp() throws Exception {
+        String path = System.getProperty("java.security.auth.login.config");
+        if (path == null) {
+            URL resource = SQLLoginModuleTest.class.getClassLoader()
+					.getResource("login.config");
+            if (resource != null) {
+                path = URLs.toFilePath(resource);
+                System.setProperty("java.security.auth.login.config", path);
+            }
+        }
+        
+        // Create the data source and initialize the database tables
+        Driver hsqlDriver = (Driver) Class.forName("org.hsqldb.jdbcDriver").newInstance();
+        Properties info = new Properties();
+        info.put("shutdown", true);
+        Connection conn = hsqlDriver.connect("jdbc:hsqldb:mem:sqltest", info);
+//        Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:sqltest");
+        conn.createStatement().execute("CREATE TABLE users (user VARCHAR(255), password VARCHAR(255))");
+        conn.createStatement().execute("CREATE TABLE groups (grp VARCHAR(255), user VARCHAR(255))");
+
+        // Add users
+        PreparedStatement st = conn.prepareStatement("INSERT INTO users VALUES(?, ?)");
+        st.setString(1, "jonathan");
+        st.setString(2, "secret");
+        st.execute();
+        st.setString(1, "daniel");
+        st.setString(2, "password");
+        st.execute();
+        st.close();
+        
+        // Add roles (groups)
+        st = conn.prepareStatement("INSERT INTO groups VALUES(?, ?)");
+        st.setString(1, "committer");
+        st.setString(2, "jonathan");
+        st.execute();
+        st.setString(1, "contributor");
+        st.setString(2, "daniel");
+        st.execute();
+        st.setString(1, "community");
+        st.setString(2, "jonathan");
+        st.execute();
+        st.setString(2, "daniel");
+        st.execute();
+        st.close();
+        
+        conn.close();
+    }
+	
+	@AfterClass
+	public static void tearDown() {
+		if (conn != null) {
+			try {
+				conn.close();
+			} catch (SQLException e) {
+				// Can't do anything about it -- ignore
+			}
+			conn = null;
+		}
+	}
+
+    @Test
+    public void testLogin() throws LoginException {
+        LoginContext context = new LoginContext("SQLLogin",
+				new UsernamePasswordCallbackHandler("jonathan", "secret"));
+        context.login();
+
+        Subject subject = context.getSubject();
+
+        assertEquals("Should have three principals", 3,
+        		subject.getPrincipals().size());
+        assertEquals("Should have one user principal", 1,
+        		subject.getPrincipals(UserPrincipal.class).size());
+        assertEquals("Should have two group principals", 2,
+        		subject.getPrincipals(GroupPrincipal.class).size());
+
+        context.logout();
+
+        assertEquals("Should have zero principals", 0,
+        		subject.getPrincipals().size());
+    }
+
+    @Test(expected = FailedLoginException.class)
+    public void testBadUseridLogin() throws LoginException {
+        LoginContext context = new LoginContext("SQLLogin",
+				new UsernamePasswordCallbackHandler("nobody", "secret"));
+        context.login();
+    }
+
+    @Test(expected = FailedLoginException.class)
+    public void testBadPWLogin() throws LoginException {
+        LoginContext context = new LoginContext("SQLLogin",
+				new UsernamePasswordCallbackHandler("jonathan", "badpass"));
+        context.login();
+    }
+
+}

Modified: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/StatelessContainerTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/StatelessContainerTest.java?rev=703061&r1=703060&r2=703061&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/StatelessContainerTest.java
(original)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/StatelessContainerTest.java
Wed Oct  8 22:25:52 2008
@@ -23,6 +23,7 @@
 import org.apache.openejb.assembler.classic.SecurityServiceInfo;
 import org.apache.openejb.assembler.classic.StatelessSessionContainerInfo;
 import org.apache.openejb.assembler.classic.TransactionServiceInfo;
+import org.apache.openejb.assembler.classic.cmd.Info2Properties;
 import org.apache.openejb.config.ConfigurationFactory;
 import org.apache.openejb.core.ivm.naming.InitContextFactory;
 import org.apache.openejb.jee.EjbJar;
@@ -78,6 +79,8 @@
             // Check the lifecycle of the bean
             assertEquals(join("\n", expected), join("\n", lifecycle));
         }
+
+        Info2Properties.printLocalConfig();
     }
 
     protected void setUp() throws Exception {

Added: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/HexConverterTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/HexConverterTest.java?rev=703061&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/HexConverterTest.java
(added)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/HexConverterTest.java
Wed Oct  8 22:25:52 2008
@@ -0,0 +1,38 @@
+package org.apache.openejb.util;
+
+import static junit.framework.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class HexConverterTest {
+
+	@Test
+	public void testBytesToHex() {
+		byte[] bytes = new byte[] { 0, 8, 10, 127, 50 };
+		String hexString = HexConverter.bytesToHex(bytes);
+		assertEquals("00080A7F32", hexString);
+	}
+
+	@Test
+	public void testStringToBytes() {
+		final byte[] correctAnswer = new byte[] { (byte) 166, (byte) 253, 0, 18, (byte) 184};
+		String hexString = "A6FD0012B8";
+		byte[] bytes = HexConverter.hexToBytes(hexString);
+		assertEquals(bytes.length, correctAnswer.length);
+		for (int i = 0; i < bytes.length; i++)
+			assertEquals(correctAnswer[i], bytes[i]);
+	}
+	
+	@Test(expected = IllegalArgumentException.class)
+	public void testWrongNumberOfDigits() {
+		String hexString = "F5D";
+		HexConverter.hexToBytes(hexString);
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testInvalidHexString() {
+		String hexString = "A9G0";
+		HexConverter.hexToBytes(hexString);
+	}
+
+}



Mime
View raw message