/* * #! * Ontopia Realm * #- * Copyright (C) 2001 - 2013 The Ontopia Project * #- * 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. * !# */ package net.ontopia.topicmaps.nav2.realm; import java.io.IOException; import java.util.Collection; import java.util.Iterator; import java.util.Map; import java.security.Principal; 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.TextOutputCallback; import javax.security.auth.callback.UnsupportedCallbackException; import org.junit.Test; import junit.framework.TestCase; /** * INTERNAL: Tests the TMLoginModule class. */ public class TMLoginModuleTest extends TestCase { public TMLoginModuleTest(String name) { super(name); } @Test public void testLoginModulePlaintextSucce() throws Exception{ String[] tokens = new String[] { "plaintext", "feil", "plaintext", "hemmelig1", "plaintext", "hemmelig3", "plaintext", "hemmelig1" }; String[] pnames = new String[] { "plaintext", "user", "Administrator" }; Map options = new java.util.HashMap(); options.put("hashmethod", "plaintext"); options.put("topicmap", "tmloginmodule.ltm"); doLoginTests(tokens, pnames, options); } @Test public void testLoginModuleBase64() throws Exception{ String[] tokens = new String[] { "base64", "feil", "base64", "hemmelig2", "base64", "hemmelig1", "base64", "hemmelig2" }; // user (small) = implicit role // User (capt) = Role topic with "User" as topicname String[] pnames = new String[] { "base64", "user", "Administrator", "Janitor", "User" }; Map options = new java.util.HashMap(); options.put("hashmethod", "base64"); options.put("topicmap", "tmloginmodule.ltm"); doLoginTests(tokens, pnames, options); } @Test public void testLoginModuleMD5() throws Exception{ String[] tokens = new String[] { "md5", "feil", "md5", "hemmelig3", "md5", "hemmelig2", "md5", "hemmelig3" }; String[] pnames = new String[] { "md5", "user" }; Map options = new java.util.HashMap(); options.put("hashmethod", "md5"); options.put("topicmap", "tmloginmodule.ltm"); doLoginTests(tokens, pnames, options); } protected void doLoginTests(String[] tokens, String[] pnames, Map options) throws Exception { TestableTMLoginModule loginModule = new TestableTMLoginModule(); Subject subject = new Subject(); CallbackHandler callbackHandler = new CallbackHandlerImpl(tokens); Map _principals = new java.util.HashMap(); loginModule.initialize( subject, callbackHandler, _principals, options); // should fail with incorrect password assertFalse("Could log in with wrong password", loginModule.login()); assertTrue("Could not log out (1)", loginModule.logout()); // should succeed assertTrue("Could not log in with correct tokens (2)", loginModule.login()); assertTrue("Could not log out (2)", loginModule.logout()); // should fail with other user's password assertFalse("Could log in with other user's password", loginModule.login()); assertTrue("Could not log out (3)", loginModule.logout()); // should succeed assertTrue("Could not log in with correct tokens", loginModule.login()); // accept last token assertTrue("Could not commit", loginModule.commit()); // verify roles Collection principals = subject.getPrincipals(); // ISSUE: all principals have just one role subject, 'user' for // the time being, totally two principals including the user // principal. //! assertTrue("Subject does not have correct number of principals", //! principals.size() == pnames.length); assertEquals("Subject does not have correct number of principals " + java.util.Arrays.asList(principals), pnames.length, principals.size()); Iterator iter = principals.iterator(); while (iter.hasNext()) { Principal principal = (Principal)iter.next(); String pname = principal.getName(); boolean ok = false; for (int i=0; i < pnames.length; i++) { if (pnames[i].equals(pname)) { ok = true; break; } } if (!ok) fail("User did not have proper principals: " + java.util.Arrays.asList(pnames)); } } static class CallbackHandlerImpl implements CallbackHandler { protected String[] tokens; protected int index; public CallbackHandlerImpl(String[] tokens) { this.tokens = tokens; } public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof NameCallback) { // prompt the user for a username NameCallback nc = (NameCallback)callbacks[i]; String username = tokens[index++]; nc.setName(username); } else if (callbacks[i] instanceof PasswordCallback) { // prompt the user for sensitive information PasswordCallback pc = (PasswordCallback)callbacks[i]; String password = tokens[index++]; pc.setPassword(password.toCharArray()); } else if (callbacks[i] instanceof TextOutputCallback) { // ignore } else { throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback"); } } } } }