/* * * 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. * under the License. */ package org.apache.karaf.jaas.modules.jdbc; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.HashMap; import java.util.Map; 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.sql.DataSource; import org.apache.derby.jdbc.EmbeddedDataSource40; import org.apache.karaf.jaas.boot.principal.GroupPrincipal; import org.apache.karaf.jaas.boot.principal.RolePrincipal; import org.apache.karaf.jaas.boot.principal.UserPrincipal; import org.easymock.EasyMock; import org.junit.Before; import org.junit.Test; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import static org.easymock.EasyMock.expect; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class JdbcLoginModuleTest { private EmbeddedDataSource40 dataSource; private Map<String, Object> options; @Before public void setUp() throws Exception { System.setProperty("derby.stream.error.file", "target/derby.log"); // Create datasource dataSource = new EmbeddedDataSource40(); dataSource.setDatabaseName("memory:db"); dataSource.setCreateDatabase("create"); // Delete tables try (Connection connection = dataSource.getConnection()) { connection.setAutoCommit(true); try { try (Statement statement = connection.createStatement()) { statement.execute("drop table USERS"); } } catch (SQLException e) { // Ignore } try { try (Statement statement = connection.createStatement()) { statement.execute("drop table ROLES"); } } catch (SQLException e) { // Ignore } connection.commit(); } // Create tables try (Connection connection = dataSource.getConnection()) { try (Statement statement = connection.createStatement()) { statement.execute("create table USERS (USERNAME VARCHAR(32) PRIMARY KEY, PASSWORD VARCHAR(32))"); } try (Statement statement = connection.createStatement()) { statement.execute("create table ROLES (USERNAME VARCHAR(32), ROLE VARCHAR(1024))"); } connection.commit(); } // Mocks BundleContext context = EasyMock.createMock(BundleContext.class); ServiceReference reference = EasyMock.createMock(ServiceReference.class); // Create options options = new HashMap<>(); options.put(JDBCUtils.DATASOURCE, "osgi:" + DataSource.class.getName()); options.put(BundleContext.class.getName(), context); expect(context.getServiceReferences(DataSource.class.getName(), null)).andReturn(new ServiceReference[] { reference }); expect((DataSource)context.getService(reference)).andReturn(dataSource); expect(context.ungetService(reference)).andReturn(true); EasyMock.replay(context); } @Test public void testLoginModule() throws Exception { JDBCBackingEngine engine = new JDBCBackingEngine(dataSource); engine.addUser("abc", "xyz"); engine.addRole("abc", "role1"); JDBCLoginModule module = new JDBCLoginModule(); Subject subject = new Subject(); module.initialize(subject, getCallbackHandler("abc", "xyz"), null, options); module.login(); module.commit(); assertFalse(subject.getPrincipals(UserPrincipal.class).isEmpty()); assertEquals("abc", subject.getPrincipals(UserPrincipal.class).iterator().next().getName()); assertFalse(subject.getPrincipals(RolePrincipal.class).isEmpty()); assertEquals("role1", subject.getPrincipals(RolePrincipal.class).iterator().next().getName()); } @Test public void testLoginModuleWithGroups() throws Exception { JDBCBackingEngine engine = new JDBCBackingEngine(dataSource); engine.addGroupRole("group1", "role2"); engine.addUser("abc", "xyz"); engine.addRole("abc", "role1"); engine.addGroup("abc", "group1"); JDBCLoginModule module = new JDBCLoginModule(); Subject subject = new Subject(); module.initialize(subject, getCallbackHandler("abc", "xyz"), null, options); module.login(); module.commit(); assertTrue(subject.getPrincipals().contains(new UserPrincipal("abc"))); assertTrue(subject.getPrincipals().contains(new GroupPrincipal("group1"))); assertTrue(subject.getPrincipals().contains(new RolePrincipal("role1"))); assertTrue(subject.getPrincipals().contains(new RolePrincipal("role2"))); } @Test public void testEngine() throws Exception { JDBCBackingEngine engine = new JDBCBackingEngine(dataSource); assertTrue(engine.listUsers().isEmpty()); engine.addUser("abc", "xyz"); assertTrue(engine.listUsers().contains(new UserPrincipal("abc"))); assertTrue(engine.listRoles(new UserPrincipal("abc")).isEmpty()); assertTrue(engine.listRoles(new GroupPrincipal("group1")).isEmpty()); assertTrue(engine.listGroups(new UserPrincipal("abc")).isEmpty()); engine.addRole("abc", "role1"); assertTrue(engine.listUsers().contains(new UserPrincipal("abc"))); assertTrue(engine.listRoles(new UserPrincipal("abc")).contains(new RolePrincipal("role1"))); assertTrue(engine.listRoles(new GroupPrincipal("group1")).isEmpty()); assertTrue(engine.listGroups(new UserPrincipal("abc")).isEmpty()); engine.addGroupRole("group1", "role2"); assertTrue(engine.listUsers().contains(new UserPrincipal("abc"))); assertTrue(engine.listRoles(new UserPrincipal("abc")).contains(new RolePrincipal("role1"))); assertTrue(engine.listRoles(new GroupPrincipal("group1")).contains(new RolePrincipal("role2"))); assertTrue(engine.listGroups(new UserPrincipal("abc")).isEmpty()); engine.addGroup("abc", "group1"); assertTrue(engine.listUsers().contains(new UserPrincipal("abc"))); assertTrue(engine.listRoles(new UserPrincipal("abc")).contains(new RolePrincipal("role1"))); assertTrue(engine.listRoles(new UserPrincipal("abc")).contains(new RolePrincipal("role2"))); assertTrue(engine.listRoles(new GroupPrincipal("group1")).contains(new RolePrincipal("role2"))); assertTrue(engine.listGroups(new UserPrincipal("abc")).contains(new GroupPrincipal("group1"))); engine.deleteRole("abc", "role1"); assertTrue(engine.listUsers().contains(new UserPrincipal("abc"))); assertTrue(engine.listRoles(new UserPrincipal("abc")).contains(new RolePrincipal("role2"))); assertTrue(engine.listRoles(new GroupPrincipal("group1")).contains(new RolePrincipal("role2"))); assertTrue(engine.listGroups(new UserPrincipal("abc")).contains(new GroupPrincipal("group1"))); engine.deleteGroupRole("group1", "role2"); assertTrue(engine.listUsers().contains(new UserPrincipal("abc"))); assertTrue(engine.listRoles(new UserPrincipal("abc")).isEmpty()); assertTrue(engine.listRoles(new GroupPrincipal("group1")).isEmpty()); assertTrue(engine.listGroups(new UserPrincipal("abc")).contains(new GroupPrincipal("group1"))); engine.addGroupRole("group1", "role3"); assertTrue(engine.listUsers().contains(new UserPrincipal("abc"))); assertTrue(engine.listRoles(new UserPrincipal("abc")).contains(new RolePrincipal("role3"))); assertTrue(engine.listRoles(new GroupPrincipal("group1")).contains(new RolePrincipal("role3"))); assertTrue(engine.listGroups(new UserPrincipal("abc")).contains(new GroupPrincipal("group1"))); engine.deleteGroup("abc", "group1"); assertTrue(engine.listUsers().contains(new UserPrincipal("abc"))); assertTrue(engine.listRoles(new UserPrincipal("abc")).isEmpty()); assertTrue(engine.listRoles(new GroupPrincipal("group1")).isEmpty()); assertTrue(engine.listGroups(new UserPrincipal("abc")).isEmpty()); engine.deleteUser("abc"); assertTrue(engine.listUsers().isEmpty()); assertTrue(engine.listRoles(new UserPrincipal("abc")).isEmpty()); assertTrue(engine.listRoles(new GroupPrincipal("group1")).isEmpty()); assertTrue(engine.listGroups(new UserPrincipal("abc")).isEmpty()); } private CallbackHandler getCallbackHandler(final String user, final String password) { return new CallbackHandler() { @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback cb : callbacks) { if (cb instanceof NameCallback) { ((NameCallback) cb).setName(user); } else if (cb instanceof PasswordCallback) { ((PasswordCallback) cb).setPassword(password.toCharArray()); } } } }; } }