From cf864337c13b4638c588badf3f589f9e39318c95 Mon Sep 17 00:00:00 2001 From: Trevor Bramwell Date: Mon, 12 Sep 2016 11:06:56 -0700 Subject: Move ODL-AAA-MOON under 'upstream' Directory Change-Id: Ie010fbe3899e151421940908dbe8675aade54e2d Signed-off-by: Trevor Bramwell --- .../opendaylight/aaa/shiro/ServiceProxyTest.java | 45 ++++ .../org/opendaylight/aaa/shiro/TestAppender.java | 67 ++++++ .../shiro/authorization/DefaultRBACRulesTest.java | 43 ++++ .../aaa/shiro/authorization/RBACRuleTest.java | 106 +++++++++ .../shiro/filters/AuthenticationListenerTest.java | 72 ++++++ .../filters/AuthenticationTokenUtilsTest.java | 124 +++++++++++ .../aaa/shiro/realm/ODLJndiLdapRealmTest.java | 246 +++++++++++++++++++++ .../aaa/shiro/realm/TokenAuthRealmTest.java | 139 ++++++++++++ .../shiro/web/env/KarafIniWebEnvironmentTest.java | 76 +++++++ .../aaa-shiro/src/test/resources/logback-test.xml | 21 ++ 10 files changed, 939 insertions(+) create mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/ServiceProxyTest.java create mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/TestAppender.java create mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/authorization/DefaultRBACRulesTest.java create mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/authorization/RBACRuleTest.java create mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/filters/AuthenticationListenerTest.java create mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/filters/AuthenticationTokenUtilsTest.java create mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/realm/ODLJndiLdapRealmTest.java create mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/realm/TokenAuthRealmTest.java create mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/web/env/KarafIniWebEnvironmentTest.java create mode 100644 upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/resources/logback-test.xml (limited to 'upstream/odl-aaa-moon/aaa/aaa-shiro/src/test') diff --git a/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/ServiceProxyTest.java b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/ServiceProxyTest.java new file mode 100644 index 00000000..2d9c8976 --- /dev/null +++ b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/ServiceProxyTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.aaa.shiro; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.opendaylight.aaa.shiro.filters.AAAFilter; + +/** + * @author Ryan Goulding (ryandgoulding@gmail.com) + */ +public class ServiceProxyTest { + + @Test + public void testGetInstance() { + // ensures that singleton pattern is working + assertNotNull(ServiceProxy.getInstance()); + } + + @Test + public void testGetSetEnabled() { + // combines set and get tests. These are important in this instance, + // because getEnabled allows an optional callback Filter. + ServiceProxy.getInstance().setEnabled(true); + assertTrue(ServiceProxy.getInstance().getEnabled(null)); + + AAAFilter testFilter = new AAAFilter(); + // register the filter + ServiceProxy.getInstance().getEnabled(testFilter); + assertTrue(testFilter.isEnabled()); + + ServiceProxy.getInstance().setEnabled(false); + assertFalse(ServiceProxy.getInstance().getEnabled(testFilter)); + assertFalse(testFilter.isEnabled()); + } +} diff --git a/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/TestAppender.java b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/TestAppender.java new file mode 100644 index 00000000..ec9375dc --- /dev/null +++ b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/TestAppender.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2016 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.aaa.shiro; + +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.AppenderBase; + +import java.util.List; +import java.util.Vector; + +/** + * A custom slf4j Appender which stores LoggingEvent(s) in memory + * for future retrieval. This is useful from inside test resources. This class is specified + * within logback-test.xml. + * + * @author Ryan Goulding (ryandgoulding@gmail.com) + */ +public class TestAppender extends AppenderBase { + + /** + * stores all log events in memory, instead of file + */ + private List events = new Vector<>(); + + /** + * Since junit maven & junit instantiate the logging appender (as provided + * by logback-test.xml), singleton is not possible. The next best thing is to track the + * current instance so it can be retrieved by Test instances. + */ + private static volatile TestAppender currentInstance; + + /** + * keeps track of the current instance + */ + public TestAppender() { + currentInstance = this; + } + + @Override + protected void append(final LoggingEvent e) { + events.add(e); + } + + /** + * Extract the log. + * + * @return the in-memory representation of LoggingEvent(s) + */ + public List getEvents() { + return events; + } + + /** + * A way to extract the appender from Test instances. + * + * @return this + */ + public static TestAppender getCurrentInstance() { + return currentInstance; + } +} diff --git a/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/authorization/DefaultRBACRulesTest.java b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/authorization/DefaultRBACRulesTest.java new file mode 100644 index 00000000..38658f0c --- /dev/null +++ b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/authorization/DefaultRBACRulesTest.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.aaa.shiro.authorization; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import com.google.common.collect.Sets; +import java.util.Collection; +import org.junit.Test; + +/** + * A few basic test cases for the DefualtRBACRules singleton container. + * + * @author Ryan Goulding (ryandgoulding@gmail.com) + * + */ +public class DefaultRBACRulesTest { + + @Test + public void testGetInstance() { + assertNotNull(DefaultRBACRules.getInstance()); + assertEquals(DefaultRBACRules.getInstance(), DefaultRBACRules.getInstance()); + } + + @Test + public void testGetRBACRules() { + Collection rbacRules = DefaultRBACRules.getInstance().getRBACRules(); + assertNotNull(rbacRules); + + // check that a copy was returned + int originalSize = rbacRules.size(); + rbacRules.add(RBACRule.createAuthorizationRule("fakeurl/*", Sets.newHashSet("admin"))); + assertEquals(originalSize, DefaultRBACRules.getInstance().getRBACRules().size()); + } + +} diff --git a/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/authorization/RBACRuleTest.java b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/authorization/RBACRuleTest.java new file mode 100644 index 00000000..825fe626 --- /dev/null +++ b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/authorization/RBACRuleTest.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2015 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.aaa.shiro.authorization; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.Sets; +import java.util.Collection; +import java.util.HashSet; +import org.junit.Test; + +public class RBACRuleTest { + + private static final String BASIC_RBAC_RULE_URL_PATTERN = "/*"; + private static final Collection BASIC_RBAC_RULE_ROLES = Sets.newHashSet("admin"); + private RBACRule basicRBACRule = RBACRule.createAuthorizationRule(BASIC_RBAC_RULE_URL_PATTERN, + BASIC_RBAC_RULE_ROLES); + + private static final String COMPLEX_RBAC_RULE_URL_PATTERN = "/auth/v1/"; + private static final Collection COMPLEX_RBAC_RULE_ROLES = Sets.newHashSet("admin", + "user"); + private RBACRule complexRBACRule = RBACRule.createAuthorizationRule( + COMPLEX_RBAC_RULE_URL_PATTERN, COMPLEX_RBAC_RULE_ROLES); + + @Test + public void testCreateAuthorizationRule() { + // positive test cases + assertNotNull(RBACRule.createAuthorizationRule(BASIC_RBAC_RULE_URL_PATTERN, + BASIC_RBAC_RULE_ROLES)); + assertNotNull(RBACRule.createAuthorizationRule(COMPLEX_RBAC_RULE_URL_PATTERN, + COMPLEX_RBAC_RULE_ROLES)); + + // negative test cases + // both null + assertNull(RBACRule.createAuthorizationRule(null, null)); + + // url pattern is null + assertNull(RBACRule.createAuthorizationRule(null, BASIC_RBAC_RULE_ROLES)); + // url pattern is empty string + assertNull(RBACRule.createAuthorizationRule("", BASIC_RBAC_RULE_ROLES)); + + // roles is null + assertNull(RBACRule.createAuthorizationRule(BASIC_RBAC_RULE_URL_PATTERN, null)); + // roles is empty collection + assertNull(RBACRule.createAuthorizationRule(COMPLEX_RBAC_RULE_URL_PATTERN, + new HashSet())); + } + + @Test + public void testGetUrlPattern() { + assertEquals(BASIC_RBAC_RULE_URL_PATTERN, basicRBACRule.getUrlPattern()); + assertEquals(COMPLEX_RBAC_RULE_URL_PATTERN, complexRBACRule.getUrlPattern()); + } + + @Test + public void testGetRoles() { + assertTrue(BASIC_RBAC_RULE_ROLES.containsAll(basicRBACRule.getRoles())); + basicRBACRule.getRoles().clear(); + // test that getRoles() produces a new object + assertFalse(basicRBACRule.getRoles().isEmpty()); + assertTrue(basicRBACRule.getRoles().containsAll(BASIC_RBAC_RULE_ROLES)); + + assertTrue(COMPLEX_RBAC_RULE_ROLES.containsAll(complexRBACRule.getRoles())); + complexRBACRule.getRoles().add("newRole"); + // test that getRoles() produces a new object + assertFalse(complexRBACRule.getRoles().contains("newRole")); + assertTrue(complexRBACRule.getRoles().containsAll(COMPLEX_RBAC_RULE_ROLES)); + } + + @Test + public void testGetRolesInShiroFormat() { + final String BASIC_RBAC_RULE_EXPECTED_SHIRO_FORMAT = "roles[admin]"; + assertEquals(BASIC_RBAC_RULE_EXPECTED_SHIRO_FORMAT, basicRBACRule.getRolesInShiroFormat()); + + // set ordering is not predictable, so both formats must be considered + final String COMPLEX_RBAC_RULE_EXPECTED_SHIRO_FORMAT_1 = "roles[admin, user]"; + final String COMPLEX_RBAC_RULE_EXPECTED_SHIRO_FORMAT_2 = "roles[user, admin]"; + assertTrue(COMPLEX_RBAC_RULE_EXPECTED_SHIRO_FORMAT_1.equals(complexRBACRule + .getRolesInShiroFormat()) + || COMPLEX_RBAC_RULE_EXPECTED_SHIRO_FORMAT_2.equals(complexRBACRule + .getRolesInShiroFormat())); + } + + @Test + public void testToString() { + final String BASIC_RBAC_RULE_EXPECTED_SHIRO_FORMAT = "/*=roles[admin]"; + assertEquals(BASIC_RBAC_RULE_EXPECTED_SHIRO_FORMAT, basicRBACRule.toString()); + + // set ordering is not predictable,s o both formats must be considered + final String COMPLEX_RBAC_RULE_EXPECTED_SHIRO_FORMAT_1 = "/auth/v1/=roles[admin, user]"; + final String COMPLEX_RBAC_RULE_EXPECTED_SHIRO_FORMAT_2 = "/auth/v1/=roles[user, admin]"; + assertTrue(COMPLEX_RBAC_RULE_EXPECTED_SHIRO_FORMAT_1.equals(complexRBACRule.toString()) + || COMPLEX_RBAC_RULE_EXPECTED_SHIRO_FORMAT_2.equals(complexRBACRule.toString())); + } + +} diff --git a/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/filters/AuthenticationListenerTest.java b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/filters/AuthenticationListenerTest.java new file mode 100644 index 00000000..1c823525 --- /dev/null +++ b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/filters/AuthenticationListenerTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.aaa.shiro.filters; + +import static org.junit.Assert.*; + +import ch.qos.logback.classic.spi.LoggingEvent; + +import java.util.List; + +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.SimpleAuthenticationInfo; +import org.apache.shiro.authc.UsernamePasswordToken; +import org.junit.Test; +import org.opendaylight.aaa.shiro.TestAppender; +import org.opendaylight.aaa.shiro.filters.AuthenticationListener; + +/** + * Test AuthenticationListener, which is responsible for logging Accounting events. + * + * @author Ryan Goulding (ryandgoulding@gmail.com) + */ +public class AuthenticationListenerTest { + + @Test + public void testOnSuccess() throws Exception { + // sets up a successful authentication attempt + final AuthenticationListener authenticationListener = new AuthenticationListener(); + final UsernamePasswordToken authenticationToken = new UsernamePasswordToken(); + authenticationToken.setUsername("successfulUser1"); + authenticationToken.setHost("successfulHost1"); + final SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(); + // the following call produces accounting output + authenticationListener.onSuccess(authenticationToken, simpleAuthenticationInfo); + + // grab the latest log output and make sure it is in line with what is expected + final List loggingEvents = TestAppender.getCurrentInstance().getEvents(); + // the latest logging event is the one we need to inspect + final int whichLoggingEvent = loggingEvents.size() - 1; + final LoggingEvent latestLoggingEvent = loggingEvents.get(whichLoggingEvent); + final String latestLogMessage = latestLoggingEvent.getMessage(); + assertEquals("Successful authentication attempt by successfulUser1 from successfulHost1", + latestLogMessage); + } + + @Test + public void testOnFailure() throws Exception { + // variables for an unsucessful authentication attempt + final AuthenticationListener authenticationListener = new AuthenticationListener(); + final UsernamePasswordToken authenticationToken = new UsernamePasswordToken(); + authenticationToken.setUsername("unsuccessfulUser1"); + authenticationToken.setHost("unsuccessfulHost1"); + final AuthenticationException authenticationException = + new AuthenticationException("test auth exception"); + // produces unsuccessful authentication attempt output + authenticationListener.onFailure(authenticationToken, authenticationException); + + // grab the latest log output and ensure it is in line with what is expected + final List loggingEvents = TestAppender.getCurrentInstance().getEvents(); + final int whichLoggingEvent = loggingEvents.size() - 1; + final LoggingEvent latestLoggingEvent = loggingEvents.get(whichLoggingEvent); + final String latestLogMessage = latestLoggingEvent.getMessage(); + assertEquals("Unsuccessful authentication attempt by unsuccessfulUser1 from unsuccessfulHost1", + latestLogMessage); + } +} \ No newline at end of file diff --git a/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/filters/AuthenticationTokenUtilsTest.java b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/filters/AuthenticationTokenUtilsTest.java new file mode 100644 index 00000000..09331c52 --- /dev/null +++ b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/filters/AuthenticationTokenUtilsTest.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2016 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.aaa.shiro.filters; + +import static org.junit.Assert.*; + +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.authc.UsernamePasswordToken; +import org.junit.Test; +import org.opendaylight.aaa.shiro.filters.AuthenticationTokenUtils; + +/** + * Tests authentication token output utilities. + * + * @author Ryan Goulding (ryandgoulding@gmail.com) + */ +public class AuthenticationTokenUtilsTest { + + /** + * A sample non-UsernamePasswordToken implementation for testing. + */ + private final class NotUsernamePasswordToken implements AuthenticationToken { + + @Override + public Object getPrincipal() { + return null; + } + + @Override + public Object getCredentials() { + return null; + } + } + + @Test + public void testIsUsernamePasswordToken() throws Exception { + // null test + final AuthenticationToken nullUsernamePasswordToken = null; + assertFalse(AuthenticationTokenUtils.isUsernamePasswordToken(nullUsernamePasswordToken)); + + // alternate implementation of AuthenticationToken + final AuthenticationToken notUsernamePasswordToken = new NotUsernamePasswordToken(); + assertFalse(AuthenticationTokenUtils.isUsernamePasswordToken(notUsernamePasswordToken)); + + // positive test case + final AuthenticationToken positiveUsernamePasswordToken = new UsernamePasswordToken(); + assertTrue(AuthenticationTokenUtils.isUsernamePasswordToken(positiveUsernamePasswordToken)); + + } + + @Test + public void testExtractUsername() throws Exception { + // null test + final AuthenticationToken nullAuthenticationToken = null; + assertEquals(AuthenticationTokenUtils.DEFAULT_TOKEN, + AuthenticationTokenUtils.extractUsername(nullAuthenticationToken)); + + // non-UsernamePasswordToken test + final AuthenticationToken notUsernamePasswordToken = new NotUsernamePasswordToken(); + assertEquals(AuthenticationTokenUtils.DEFAULT_TOKEN, + AuthenticationTokenUtils.extractUsername(notUsernamePasswordToken)); + + // null username test + final UsernamePasswordToken nullUsername = new UsernamePasswordToken(); + nullUsername.setUsername(null); + assertEquals(AuthenticationTokenUtils.DEFAULT_USERNAME, + AuthenticationTokenUtils.extractUsername(nullUsername)); + + // positive test + final UsernamePasswordToken positiveUsernamePasswordToken = new UsernamePasswordToken(); + final String testUsername = "testUser1"; + positiveUsernamePasswordToken.setUsername(testUsername); + assertEquals(testUsername, AuthenticationTokenUtils.extractUsername(positiveUsernamePasswordToken)); + } + + @Test + public void testExtractHostname() throws Exception { + // null test + final AuthenticationToken nullAuthenticationToken = null; + assertEquals(AuthenticationTokenUtils.DEFAULT_HOSTNAME, + AuthenticationTokenUtils.extractHostname(nullAuthenticationToken)); + + // non-UsernamePasswordToken test + final AuthenticationToken notUsernamePasswordToken = new NotUsernamePasswordToken(); + assertEquals(AuthenticationTokenUtils.DEFAULT_HOSTNAME, + AuthenticationTokenUtils.extractHostname(notUsernamePasswordToken)); + + // null hostname test + final UsernamePasswordToken nullHostname = new UsernamePasswordToken(); + nullHostname.setHost(null); + assertEquals(AuthenticationTokenUtils.DEFAULT_HOSTNAME, + AuthenticationTokenUtils.extractHostname(nullHostname)); + + // positive test + final UsernamePasswordToken positiveUsernamePasswordToken = new UsernamePasswordToken(); + final String testUsername = "testHostname1"; + positiveUsernamePasswordToken.setHost(testUsername); + assertEquals(testUsername, AuthenticationTokenUtils.extractHostname(positiveUsernamePasswordToken)); + } + + @Test + public void testGenerateUnsuccessfulAuthenticationMessage() throws Exception { + final UsernamePasswordToken unsuccessfulToken = new UsernamePasswordToken(); + unsuccessfulToken.setUsername("unsuccessfulUser1"); + unsuccessfulToken.setHost("unsuccessfulHost1"); + assertEquals("Unsuccessful authentication attempt by unsuccessfulUser1 from unsuccessfulHost1", + AuthenticationTokenUtils.generateUnsuccessfulAuthenticationMessage(unsuccessfulToken)); + } + + @Test + public void testGenerateSuccessfulAuthenticationMessage() throws Exception { + final UsernamePasswordToken successfulToken = new UsernamePasswordToken(); + successfulToken.setUsername("successfulUser1"); + successfulToken.setHost("successfulHost1"); + assertEquals("Successful authentication attempt by successfulUser1 from successfulHost1", + AuthenticationTokenUtils.generateSuccessfulAuthenticationMessage(successfulToken)); + } +} diff --git a/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/realm/ODLJndiLdapRealmTest.java b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/realm/ODLJndiLdapRealmTest.java new file mode 100644 index 00000000..22ce203f --- /dev/null +++ b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/realm/ODLJndiLdapRealmTest.java @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2015 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.aaa.shiro.realm; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.Vector; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.BasicAttributes; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; +import javax.naming.ldap.LdapContext; +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.authc.UsernamePasswordToken; +import org.apache.shiro.authz.AuthorizationInfo; +import org.apache.shiro.realm.ldap.LdapContextFactory; +import org.apache.shiro.subject.PrincipalCollection; +import org.junit.Test; + +/** + * @author Ryan Goulding (ryandgoulding@gmail.com) + */ +public class ODLJndiLdapRealmTest { + + /** + * throw-away anonymous test class + */ + class TestNamingEnumeration implements NamingEnumeration { + + /** + * state variable + */ + boolean first = true; + + /** + * returned the first time next() or + * nextElement() is called. + */ + SearchResult searchResult = new SearchResult("testuser", null, new BasicAttributes( + "objectClass", "engineering")); + + /** + * returns true the first time, then false for subsequent calls + */ + @Override + public boolean hasMoreElements() { + return first; + } + + /** + * returns searchResult then null for subsequent calls + */ + @Override + public SearchResult nextElement() { + if (first) { + first = false; + return searchResult; + } + return null; + } + + /** + * does nothing because close() doesn't require any special behavior + */ + @Override + public void close() throws NamingException { + } + + /** + * returns true the first time, then false for subsequent calls + */ + @Override + public boolean hasMore() throws NamingException { + return first; + } + + /** + * returns searchResult then null for subsequent calls + */ + @Override + public SearchResult next() throws NamingException { + if (first) { + first = false; + return searchResult; + } + return null; + } + }; + + /** + * throw away test class + * + * @author ryan + */ + class TestPrincipalCollection implements PrincipalCollection { + /** + * + */ + private static final long serialVersionUID = -1236759619455574475L; + + Vector collection = new Vector(); + + public TestPrincipalCollection(String element) { + collection.add(element); + } + + @Override + public Iterator iterator() { + return collection.iterator(); + } + + @Override + public List asList() { + return collection; + } + + @Override + public Set asSet() { + HashSet set = new HashSet(); + set.addAll(collection); + return set; + } + + @Override + public Collection byType(Class arg0) { + return null; + } + + @Override + public Collection fromRealm(String arg0) { + return collection; + } + + @Override + public Object getPrimaryPrincipal() { + return collection.firstElement(); + } + + @Override + public Set getRealmNames() { + return null; + } + + @Override + public boolean isEmpty() { + return collection.isEmpty(); + } + + @Override + public T oneByType(Class arg0) { + // TODO Auto-generated method stub + return null; + } + }; + + @Test + public void testGetUsernameAuthenticationToken() { + AuthenticationToken authenticationToken = null; + assertNull(ODLJndiLdapRealm.getUsername(authenticationToken)); + AuthenticationToken validAuthenticationToken = new UsernamePasswordToken("test", + "testpassword"); + assertEquals("test", ODLJndiLdapRealm.getUsername(validAuthenticationToken)); + } + + @Test + public void testGetUsernamePrincipalCollection() { + PrincipalCollection pc = null; + assertNull(new ODLJndiLdapRealm().getUsername(pc)); + TestPrincipalCollection tpc = new TestPrincipalCollection("testuser"); + String username = new ODLJndiLdapRealm().getUsername(tpc); + assertEquals("testuser", username); + } + + @Test + public void testQueryForAuthorizationInfoPrincipalCollectionLdapContextFactory() + throws NamingException { + LdapContext ldapContext = mock(LdapContext.class); + // emulates an ldap search and returns the mocked up test class + when( + ldapContext.search((String) any(), (String) any(), + (SearchControls) any())).thenReturn(new TestNamingEnumeration()); + LdapContextFactory ldapContextFactory = mock(LdapContextFactory.class); + when(ldapContextFactory.getSystemLdapContext()).thenReturn(ldapContext); + AuthorizationInfo authorizationInfo = new ODLJndiLdapRealm().queryForAuthorizationInfo( + new TestPrincipalCollection("testuser"), ldapContextFactory); + assertNotNull(authorizationInfo); + assertFalse(authorizationInfo.getRoles().isEmpty()); + assertTrue(authorizationInfo.getRoles().contains("engineering")); + } + + @Test + public void testBuildAuthorizationInfo() { + assertNull(ODLJndiLdapRealm.buildAuthorizationInfo(null)); + Set roleNames = new HashSet(); + roleNames.add("engineering"); + AuthorizationInfo authorizationInfo = ODLJndiLdapRealm.buildAuthorizationInfo(roleNames); + assertNotNull(authorizationInfo); + assertFalse(authorizationInfo.getRoles().isEmpty()); + assertTrue(authorizationInfo.getRoles().contains("engineering")); + } + + @Test + public void testGetRoleNamesForUser() throws NamingException { + ODLJndiLdapRealm ldapRealm = new ODLJndiLdapRealm(); + LdapContext ldapContext = mock(LdapContext.class); + + // emulates an ldap search and returns the mocked up test class + when( + ldapContext.search((String) any(), (String) any(), + (SearchControls) any())).thenReturn(new TestNamingEnumeration()); + + // extracts the roles for "testuser" and ensures engineering is returned + Set roles = ldapRealm.getRoleNamesForUser("testuser", ldapContext); + assertFalse(roles.isEmpty()); + assertTrue(roles.iterator().next().equals("engineering")); + } + + @Test + public void testCreateSearchControls() { + SearchControls searchControls = ODLJndiLdapRealm.createSearchControls(); + assertNotNull(searchControls); + int expectedSearchScope = SearchControls.SUBTREE_SCOPE; + int actualSearchScope = searchControls.getSearchScope(); + assertEquals(expectedSearchScope, actualSearchScope); + } + +} diff --git a/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/realm/TokenAuthRealmTest.java b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/realm/TokenAuthRealmTest.java new file mode 100644 index 00000000..f2eb92b5 --- /dev/null +++ b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/realm/TokenAuthRealmTest.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2015 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.aaa.shiro.realm; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.google.common.collect.Lists; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.shiro.authc.AuthenticationToken; +import org.junit.Test; + +/** + * + * @author Ryan Goulding (ryandgoulding@gmail.com) + * + */ +public class TokenAuthRealmTest extends TokenAuthRealm { + + private TokenAuthRealm testRealm = new TokenAuthRealm(); + + @Test + public void testTokenAuthRealm() { + assertEquals("TokenAuthRealm", testRealm.getName()); + } + + @Test(expected = NullPointerException.class) + public void testDoGetAuthorizationInfoPrincipalCollectionNullCacheToken() { + testRealm.doGetAuthorizationInfo(null); + } + + @Test + public void testGetUsernamePasswordDomainString() { + final String username = "user"; + final String password = "password"; + final String domain = "domain"; + final String expectedUsernamePasswordString = "user:password:domain"; + assertEquals(expectedUsernamePasswordString, getUsernamePasswordDomainString(username, password, domain)); + } + + @Test + public void testGetEncodedToken() { + final String stringToEncode = "admin1:admin1"; + final byte[] bytesToEncode = stringToEncode.getBytes(); + final String expectedToken = org.apache.shiro.codec.Base64.encodeToString(bytesToEncode); + assertEquals(expectedToken, getEncodedToken(stringToEncode)); + } + + @Test + public void testGetTokenAuthHeader() { + final String encodedCredentials = getEncodedToken(getUsernamePasswordDomainString("user1", + "password", "sdn")); + final String expectedTokenAuthHeader = "Basic " + encodedCredentials; + assertEquals(expectedTokenAuthHeader, getTokenAuthHeader(encodedCredentials)); + } + + @Test + public void testFormHeadersWithToken() { + final String authHeader = getEncodedToken(getTokenAuthHeader(getUsernamePasswordDomainString( + "user1", "password", "sdn"))); + final Map> expectedHeaders = new HashMap>(); + expectedHeaders.put("Authorization", Lists.newArrayList(authHeader)); + final Map> actualHeaders = formHeadersWithToken(authHeader); + List value; + for (String key : expectedHeaders.keySet()) { + value = expectedHeaders.get(key); + assertTrue(actualHeaders.get(key).equals(value)); + } + } + + @Test + public void testFormHeaders() { + final String username = "basicUser"; + final String password = "basicPassword"; + final String domain = "basicDomain"; + final String authHeader = getTokenAuthHeader(getEncodedToken(getUsernamePasswordDomainString( + username, password, domain))); + final Map> expectedHeaders = new HashMap>(); + expectedHeaders.put("Authorization", Lists.newArrayList(authHeader)); + final Map> actualHeaders = formHeaders(username, password, domain); + List value; + for (String key : expectedHeaders.keySet()) { + value = expectedHeaders.get(key); + assertTrue(actualHeaders.get(key).equals(value)); + } + } + + @Test + public void testIsTokenAuthAvailable() { + assertFalse(testRealm.isTokenAuthAvailable()); + } + + @Test(expected = org.apache.shiro.authc.AuthenticationException.class) + public void testDoGetAuthenticationInfoAuthenticationToken() { + testRealm.doGetAuthenticationInfo(null); + } + + @Test + public void testExtractUsernameNullUsername() { + AuthenticationToken at = mock(AuthenticationToken.class); + when(at.getPrincipal()).thenReturn(null); + assertNull(extractUsername(at)); + } + + @Test(expected = ClassCastException.class) + public void testExtractPasswordNullPassword() { + AuthenticationToken at = mock(AuthenticationToken.class); + when(at.getPrincipal()).thenReturn("username"); + when(at.getCredentials()).thenReturn(null); + extractPassword(at); + } + + @Test(expected = ClassCastException.class) + public void testExtractUsernameBadUsernameClass() { + AuthenticationToken at = mock(AuthenticationToken.class); + when(at.getPrincipal()).thenReturn(new Integer(1)); + extractUsername(at); + } + + @Test(expected = ClassCastException.class) + public void testExtractPasswordBadPasswordClass() { + AuthenticationToken at = mock(AuthenticationToken.class); + when(at.getPrincipal()).thenReturn("username"); + when(at.getCredentials()).thenReturn(new Integer(1)); + extractPassword(at); + } +} diff --git a/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/web/env/KarafIniWebEnvironmentTest.java b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/web/env/KarafIniWebEnvironmentTest.java new file mode 100644 index 00000000..141d0ce5 --- /dev/null +++ b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/java/org/opendaylight/aaa/shiro/web/env/KarafIniWebEnvironmentTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2015 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.aaa.shiro.web.env; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import org.apache.shiro.config.Ini; +import org.apache.shiro.config.Ini.Section; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * @author Ryan Goulding (ryandgoulding@gmail.com) + */ +public class KarafIniWebEnvironmentTest { + private static File iniFile; + + @BeforeClass + public static void setup() throws IOException { + iniFile = createShiroIniFile(); + assertTrue(iniFile.exists()); + } + + @AfterClass + public static void teardown() { + iniFile.delete(); + } + + private static String createFakeShiroIniContents() { + return "[users]\n" + "admin=admin, ROLE_ADMIN \n" + "[roles]\n" + "ROLE_ADMIN = *\n" + + "[urls]\n" + "/** = authcBasic"; + } + + private static File createShiroIniFile() throws IOException { + File shiroIni = File.createTempFile("shiro", "ini"); + FileWriter writer = new FileWriter(shiroIni); + writer.write(createFakeShiroIniContents()); + writer.flush(); + writer.close(); + return shiroIni; + } + + @Test + public void testCreateShiroIni() throws IOException { + Ini ini = KarafIniWebEnvironment.createShiroIni(iniFile.getAbsolutePath()); + assertNotNull(ini); + assertNotNull(ini.getSection("users")); + assertNotNull(ini.getSection("roles")); + assertNotNull(ini.getSection("urls")); + Section usersSection = ini.getSection("users"); + assertTrue(usersSection.containsKey("admin")); + assertTrue(usersSection.get("admin").contains("admin")); + assertTrue(usersSection.get("admin").contains("ROLE_ADMIN")); + } + + @Test + public void testCreateFileBasedIniPath() { + String testPath = "/shiro.ini"; + String expectedFileBasedIniPath = KarafIniWebEnvironment.SHIRO_FILE_PREFIX + testPath; + String actualFileBasedIniPath = KarafIniWebEnvironment.createFileBasedIniPath(testPath); + assertEquals(expectedFileBasedIniPath, actualFileBasedIniPath); + } + +} diff --git a/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/resources/logback-test.xml b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/resources/logback-test.xml new file mode 100644 index 00000000..68ceeabc --- /dev/null +++ b/upstream/odl-aaa-moon/aaa/aaa-shiro/src/test/resources/logback-test.xml @@ -0,0 +1,21 @@ + + + + + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + -- cgit 1.2.3-korg