--- /dev/null
+<!-- 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 -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.aaa</groupId>
+ <artifactId>aaa-parent</artifactId>
+ <version>0.3.0-SNAPSHOT</version>
+ <relativePath>../parent</relativePath>
+ </parent>
+
+ <artifactId>aaa-shiro-act</artifactId>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.aaa</groupId>
+ <artifactId>aaa-shiro</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.dependencymanager</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-beanutils</groupId>
+ <artifactId>commons-beanutils</artifactId>
+ <version>1.8.3</version>
+ </dependency>
+
+ <!-- Testing Dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${bundle.plugin.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+ </instructions>
+ <manifestLocation>${project.basedir}/META-INF</manifestLocation>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Activator>org.opendaylight.aaa.shiroact.Activator</Bundle-Activator>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+/*
+ * 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.shiroact;
+
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.opendaylight.aaa.shiro.ServiceProxy;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Responsible for activating the aaa-shiro-act bundle. This bundle is primarily
+ * responsible for enabling AuthN and AuthZ. If this bundle is not installed,
+ * then AuthN and AuthZ will not take effect.
+ *
+ * To ensure that the AAA is enabled for your feature, make sure to include the
+ * <code>odl-aaa-shiro</code> feature in your feature definition.
+ *
+ * Offers contextual <code>DEBUG</code> level clues concerning the activation of
+ * the <code>aaa-shiro-act</code> bundle. To enable the enhanced debugging issue
+ * the following line in the karaf shell:
+ * <code>log:set debug org.opendaylight.aaa.shiroact.Activator</code>
+ *
+ * @author Ryan Goulding (ryandgoulding@gmail.com)
+ */
+public class Activator extends DependencyActivatorBase {
+
+ private static Logger LOG = LoggerFactory.getLogger(Activator.class);
+
+ @Override
+ public void destroy(BundleContext bc, DependencyManager dm)
+ throws Exception {
+ final String DEBUG_MESSAGE = "Destroying the aaa-shiro-act bundle";
+ LOG.debug(DEBUG_MESSAGE);
+ }
+
+ @Override
+ public void init(BundleContext bc, DependencyManager dm) throws Exception {
+ final String DEBUG_MESSAGE = "Initializing the aaa-shiro-act bundle";
+ LOG.debug(DEBUG_MESSAGE);
+ ServiceProxy.getInstance().setEnabled(true);
+ }
+
+}
--- /dev/null
+package org.opendaylight.aaa.shiroact;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.opendaylight.aaa.shiro.ServiceProxy;
+
+public class ActivatorTest {
+
+ @Test
+ public void testActivatorEnablesServiceProxy() throws Exception {
+ // should toggle the ServiceProxy enable status to true
+ new Activator().init(null, null);;
+ assertTrue(ServiceProxy.getInstance().getEnabled(null));
+ }
+
+}
-<!--
- 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
--->
+<!-- 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 -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.aaa</groupId>
- <artifactId>aaa-parent</artifactId>
- <version>0.3.0-SNAPSHOT</version>
- <relativePath>../parent</relativePath>
- </parent>
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.aaa</groupId>
+ <artifactId>aaa-parent</artifactId>
+ <version>0.3.0-SNAPSHOT</version>
+ <relativePath>../parent</relativePath>
+ </parent>
- <artifactId>aaa-shiro</artifactId>
- <packaging>bundle</packaging>
+ <artifactId>aaa-shiro</artifactId>
+ <packaging>bundle</packaging>
- <dependencies>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.dependencymanager</artifactId>
- </dependency>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.dependencymanager</artifactId>
+ </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-core</artifactId>
- <version>1.2.3</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-web</artifactId>
- <version>1.2.3</version>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>commons-beanutils</groupId>
- <artifactId>commons-beanutils</artifactId>
- <version>1.8.3</version>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- </dependency>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-core</artifactId>
+ <version>1.2.3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-web</artifactId>
+ <version>1.2.3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-beanutils</groupId>
+ <artifactId>commons-beanutils</artifactId>
+ <version>1.8.3</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </dependency>
- <!-- Testing Dependencies -->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
- <build>
- <pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
- </instructions>
- <manifestLocation>${project.basedir}/META-INF</manifestLocation>
- </configuration>
- </plugin>
- </plugins>
- </pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-Activator>org.opendaylight.aaa.shiro.Activator</Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>attach-artifacts</id>
- <phase>package</phase>
- <goals>
- <goal>attach-artifact</goal>
- </goals>
- <configuration>
- <artifacts>
- <artifact>
- <file>${project.build.directory}/classes/shiro.ini</file>
- <type>ini</type>
- <classifier>config</classifier>
- </artifact>
- </artifacts>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
+ <!-- Testing Dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${bundle.plugin.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+ </instructions>
+ <manifestLocation>${project.basedir}/META-INF</manifestLocation>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Activator>org.opendaylight.aaa.shiro.Activator</Bundle-Activator>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <phase>package</phase>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/shiro.ini</file>
+ <type>cfg</type>
+ <classifier>configuration</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
</project>
import org.slf4j.LoggerFactory;
/**
- * Offers contextual <code>DEBUG</code> level clues concerning the activation
- * of the <code>aaa-shiro</code> bundle.
+ * This scaffolding allows the use of AAA Filters without AuthN or AuthZ
+ * enabled. This is done to support workflows such as those included in the
+ * <code>odl-restconf-noauth</code> feature.
+ *
+ * This class is also responsible for offering contextual <code>DEBUG</code>
+ * level clues concerning the activation of the <code>aaa-shiro</code> bundle.
+ * To enable these debug messages, issue the following command in the karaf
+ * shell: <code>log:set debug org.opendaylight.aaa.shiro.Activator</code>
*
* @author Ryan Goulding (ryandgoulding@gmail.com)
*/
public class Activator extends DependencyActivatorBase {
- private static Logger LOG = LoggerFactory.getLogger(Activator.class);
+ private static final Logger LOG = LoggerFactory.getLogger(Activator.class);
- @Override
- public void destroy(BundleContext bc, DependencyManager dm)
- throws Exception {
- final String DEBUG_MESSAGE = "Destroying the aaa-shiro bundle";
- LOG.debug(DEBUG_MESSAGE);
- }
+ @Override
+ public void destroy(BundleContext bc, DependencyManager dm)
+ throws Exception {
+ final String DEBUG_MESSAGE = "Destroying the aaa-shiro bundle";
+ LOG.debug(DEBUG_MESSAGE);
+ }
- @Override
- public void init(BundleContext bc, DependencyManager dm) throws Exception {
- final String DEBUG_MESSAGE = "Initializing the aaa-shiro bundle";
- LOG.debug(DEBUG_MESSAGE);
- }
+ @Override
+ public void init(BundleContext bc, DependencyManager dm) throws Exception {
+ final String DEBUG_MESSAGE = "Initializing the aaa-shiro bundle";
+ LOG.debug(DEBUG_MESSAGE);
+ }
}
--- /dev/null
+package org.opendaylight.aaa.shiro;
+
+import org.opendaylight.aaa.shiro.filters.AAAFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Responsible for enabling and disabling the AAA service. By default, the
+ * service is disabled; the AAAFilter will not require AuthN or AuthZ. The
+ * service is enabled through calling
+ * <code>ServiceProxy.getInstance().setEnabled(true)</code>. AuthN and AuthZ are
+ * disabled by default in order to support workflows such as the feature
+ * <code>odl-restconf-noauth</code>.
+ *
+ * The AAA service is enabled through installing the <code>odl-aaa-shiro</code>
+ * feature. The <code>org.opendaylight.aaa.shiroact.Activator()</code>
+ * constructor calls enables AAA through the ServiceProxy, which in turn enables
+ * the AAAFilter.
+ *
+ * ServiceProxy is a singleton; access to the ServiceProxy is granted through
+ * the <code>getInstance()</code> function.
+ *
+ * @author Ryan Goulding (ryandgoulding@gmail.com)
+ * @link
+ * https://github.com/opendaylight/netconf/blob/master/opendaylight/restconf
+ * /sal-rest-connector/src/main/resources/WEB-INF/web.xml
+ * @see <code>org.opendaylight.aaa.shiro.Activator</code>
+ * @see <code>org.opendaylight.aaa.shiro.filters.AAAFilter</code>
+ */
+public class ServiceProxy {
+ private static final Logger LOG = LoggerFactory
+ .getLogger(ServiceProxy.class);
+
+ /**
+ * AuthN and AuthZ are disabled by default to support workflows included in
+ * features such as <code>odl-restconf-noauth</code>
+ */
+ public static final boolean DEFAULT_AA_ENABLE_STATUS = false;
+
+ private static ServiceProxy instance = new ServiceProxy();
+ private volatile boolean enabled = false;
+ private AAAFilter filter;
+
+ /**
+ * private for singleton pattern
+ */
+ private ServiceProxy() {
+ final String INFO_MESSAGE = "Creating the ServiceProxy";
+ LOG.info(INFO_MESSAGE);
+ }
+
+ /**
+ * @return ServiceProxy, a feature level singleton
+ */
+ public static ServiceProxy getInstance() {
+ return instance;
+ }
+
+ /**
+ * Enables/disables the feature, cascading the state information to the
+ * AAAFilter.
+ *
+ * @param enabled
+ */
+ public synchronized void setEnabled(final boolean enabled) {
+ this.enabled = enabled;
+ final String SERVICE_ENABLED_INFO_MESSAGE = "Setting ServiceProxy enabled to "
+ + enabled;
+ LOG.info(SERVICE_ENABLED_INFO_MESSAGE);
+ // check for null because of non-determinism in bundle load
+ if (filter != null) {
+ filter.setEnabled(enabled);
+ }
+ }
+
+ /**
+ * Extract whether the service is enabled.
+ *
+ * @param filter
+ * register an optional Filter for callback if enable state
+ * changes
+ * @return
+ */
+ public synchronized boolean getEnabled(final AAAFilter filter) {
+ this.filter = filter;
+ return enabled;
+ }
+}
import org.slf4j.LoggerFactory;
/**
- * Accounter is a common place to output AAA messages. Use this class through
+ * Accounter is a common place to output AAA messages. Use this class through
* invoking <code>Logger.output("message")</code>.
*
* @author Ryan Goulding (ryandgoulding@gmail.com)
*/
public class Accounter {
- private static Logger LOG = LoggerFactory.getLogger(Accounter.class);
+ private static final Logger LOG = LoggerFactory.getLogger(Accounter.class);
- /*
- * Essentially makes Accounter a singleton, avoiding the verbosity
- * of <code>Accounter.getInstance().output("message")</code>.
- */
- private Accounter() {
- }
+ /*
+ * Essentially makes Accounter a singleton, avoiding the verbosity of
+ * <code>Accounter.getInstance().output("message")</code>.
+ */
+ private Accounter() {
+ }
- /**
- * Account for a particular <code>message</code>
- *
- * @param message
- */
- public static void output(final String message) {
- LOG.debug(message);
- }
+ /**
+ * Account for a particular <code>message</code>
+ *
+ * @param message
+ */
+ public static void output(final String message) {
+ LOG.debug(message);
+ }
}
package org.opendaylight.aaa.shiro.filters;
import org.apache.shiro.web.servlet.ShiroFilter;
+import org.opendaylight.aaa.shiro.ServiceProxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * The default AAA JAX-RS 1.X Web Filter.
+ * The default AAA JAX-RS 1.X Web Filter. This class is also responsible for
+ * delivering debug information; to enable these debug statements, please issue
+ * the following in the karaf shell:
+ *
+ * <code>log:set debug org.opendaylight.aaa.shiro.filters.AAAFilter</code>
*
* @author Ryan Goulding (ryandgoulding@gmail.com)
* @see <code>javax.servlet.Filter</code>
*/
public class AAAFilter extends ShiroFilter {
- private static Logger LOG = LoggerFactory.getLogger(AAAFilter.class);
+ private static Logger LOG = LoggerFactory.getLogger(AAAFilter.class);
+
+ public AAAFilter() {
+ super();
+ final String DEBUG_MESSAGE = "Creating the AAAFilter";
+ LOG.debug(DEBUG_MESSAGE);
+ }
- public AAAFilter() {
- super();
- final String DEBUG_MESSAGE = "Creating the AAAFilter";
- LOG.debug(DEBUG_MESSAGE);
- }
+ /*
+ * (non-Javadoc)
+ *
+ * Adds context clues that aid in debugging. Also initializes the enable
+ * status to correspond with
+ * <code>ServiceProxy.getInstance.getEnabled()</code>.
+ *
+ * @see org.apache.shiro.web.servlet.ShiroFilter#init()
+ */
+ @Override
+ public void init() throws Exception {
+ super.init();
+ final String DEBUG_MESSAGE = "Initializing the AAAFilter";
+ LOG.debug(DEBUG_MESSAGE);
+ // sets the filter to the startup value. Because of non-determinism in
+ // bundle loading, this passes an instance of itself along so that if
+ // the
+ // enable status changes, then AAAFilter enable status is changed.
+ setEnabled(ServiceProxy.getInstance().getEnabled(this));
+ }
- @Override
- public void init() throws Exception {
- super.init();
- final String DEBUG_MESSAGE = "Initializing the AAAFilter";
- LOG.debug(DEBUG_MESSAGE);
- }
+ /*
+ * (non-Javadoc)
+ *
+ * Adds context clues to aid in debugging whether the filter is enabled.
+ *
+ * @see
+ * org.apache.shiro.web.servlet.OncePerRequestFilter#setEnabled(boolean)
+ */
+ @Override
+ public void setEnabled(boolean enabled) {
+ super.setEnabled(enabled);
+ final String DEBUG_MESSAGE = "Setting AAAFilter enabled to " + enabled;
+ LOG.debug(DEBUG_MESSAGE);
+ }
}
*
* @author Ryan Goulding (ryandgoulding@gmail.com)
* @see <code>org.apache.shiro.realm.ldap.JndiLdapRealm</code>
- * {@link https://shiro.apache.org/static/1.2.3/apidocs/org/apache/shiro/realm/ldap/JndiLdapRealm.html}
+ * @link {https
+ * ://shiro.apache.org/static/1.2.3/apidocs/org/apache/shiro/realm/ldap/
+ * JndiLdapRealm.html}
*/
public class ODLJndiLdapRealm extends JndiLdapRealm {
- private static final Logger LOG = LoggerFactory
- .getLogger(ODLJndiLdapRealm.class);
-
- private static final String LDAP_CONNECTION_MESSAGE = "AAA LDAP connection from ";
-
- /*
- * Adds debugging information surrounding creation of ODLJndiLdapRealm
- */
- public ODLJndiLdapRealm() {
- super();
- final String DEBUG_MESSAGE = "Creating ODLJndiLdapRealm";
- LOG.debug(DEBUG_MESSAGE);
- }
-
- /*
- * (non-Javadoc) Overridden to expose important audit trail information
- * for accounting.
- *
- * @see org.apache.shiro.realm.ldap.JndiLdapRealm#doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)
- */
- @Override
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
- throws AuthenticationException {
-
- try {
- final String username = getUsername(token);
- logIncomingConnection(username);
- return super.doGetAuthenticationInfo(token);
- } catch (ClassCastException e) {
- final String ERROR_MESSAGE = "Couldn't service the LDAP connection";
- LOG.info(ERROR_MESSAGE, e);
+ private static final Logger LOG = LoggerFactory
+ .getLogger(ODLJndiLdapRealm.class);
+
+ private static final String LDAP_CONNECTION_MESSAGE = "AAA LDAP connection from ";
+
+ /*
+ * Adds debugging information surrounding creation of ODLJndiLdapRealm
+ */
+ public ODLJndiLdapRealm() {
+ super();
+ final String DEBUG_MESSAGE = "Creating ODLJndiLdapRealm";
+ LOG.debug(DEBUG_MESSAGE);
}
- return null;
- }
-
- /**
- * Logs an incoming LDAP connection
- *
- * @param username the requesting user
- */
- protected void logIncomingConnection(final String username) {
- final String message = LDAP_CONNECTION_MESSAGE + username;
- LOG.info(message);
- Accounter.output(message);
- }
-
- /**
- * Extracts the username from <code>token</code>
- *
- * @param token
- * @return
- * @throws ClassCastException The incoming token is not username/password
- * (i.e., X.509 certificate)
- */
- public static String getUsername(AuthenticationToken token) throws ClassCastException {
- if (null == token) {
- return null;
+
+ /*
+ * (non-Javadoc) Overridden to expose important audit trail information for
+ * accounting.
+ *
+ * @see
+ * org.apache.shiro.realm.ldap.JndiLdapRealm#doGetAuthenticationInfo(org
+ * .apache.shiro.authc.AuthenticationToken)
+ */
+ @Override
+ protected AuthenticationInfo doGetAuthenticationInfo(
+ AuthenticationToken token) throws AuthenticationException {
+
+ try {
+ final String username = getUsername(token);
+ logIncomingConnection(username);
+ return super.doGetAuthenticationInfo(token);
+ } catch (ClassCastException e) {
+ final String ERROR_MESSAGE = "Couldn't service the LDAP connection";
+ LOG.info(ERROR_MESSAGE, e);
+ }
+ return null;
}
- return (String) token.getPrincipal();
- }
-
- @Override
- protected AuthorizationInfo doGetAuthorizationInfo(
- PrincipalCollection principals) {
-
- AuthorizationInfo ai = null;
- try {
- ai = this.queryForAuthorizationInfo(principals,
- getContextFactory());
- }
- catch (NamingException e) {
- e.printStackTrace();
- }
- return ai;
- }
-
- /**
- * extracts a username from <code>principals</code>
- *
- * @param principals
- * @return
- * @throws ClassCastException the PrincipalCollection contains an element
- * that is not in username/password form (i.e., X.509 certificate)
- */
- protected String getUsername(final PrincipalCollection principals)
- throws ClassCastException {
-
- if (null == principals) {
- return null;
+
+ /**
+ * Logs an incoming LDAP connection
+ *
+ * @param username
+ * the requesting user
+ */
+ protected void logIncomingConnection(final String username) {
+ final String message = LDAP_CONNECTION_MESSAGE + username;
+ LOG.info(message);
+ Accounter.output(message);
}
- return (String) getAvailablePrincipal(principals);
- }
-
- @Override
- protected AuthorizationInfo queryForAuthorizationInfo(
- PrincipalCollection principals, LdapContextFactory ldapContextFactory)
- throws NamingException {
-
- AuthorizationInfo authorizationInfo = null;
- try {
- final String username = getUsername(principals);
- LdapContext ldapContext = ldapContextFactory.getSystemLdapContext();
- Set<String> roleNames;
-
- try {
- roleNames = getRoleNamesForUser(username, ldapContext);
- authorizationInfo = buildAuthorizationInfo(roleNames);
- } finally {
- LdapUtils.closeContext(ldapContext);
- }
- } catch(ClassCastException e) {
- final String ERROR_MESSAGE = "Unable to extract a valid user";
- LOG.error(ERROR_MESSAGE, e);
+
+ /**
+ * Extracts the username from <code>token</code>
+ *
+ * @param token
+ * @return
+ * @throws ClassCastException
+ * The incoming token is not username/password (i.e., X.509
+ * certificate)
+ */
+ public static String getUsername(AuthenticationToken token)
+ throws ClassCastException {
+ if (null == token) {
+ return null;
+ }
+ return (String) token.getPrincipal();
}
- return authorizationInfo;
- }
- public static AuthorizationInfo buildAuthorizationInfo(final Set<String> roleNames) {
- if(null == roleNames) {
- return null;
+ @Override
+ protected AuthorizationInfo doGetAuthorizationInfo(
+ PrincipalCollection principals) {
+
+ AuthorizationInfo ai = null;
+ try {
+ ai = this
+ .queryForAuthorizationInfo(principals, getContextFactory());
+ } catch (NamingException e) {
+ LOG.error("Unable to query for AuthZ info: ", e);
+ }
+ return ai;
}
- return new SimpleAuthorizationInfo(roleNames);
- }
-
- /**
- * extracts the Set of roles associated with a user based on the username and
- * ldap context (server).
- *
- * @param username
- * @param ldapContext
- * @return
- * @throws NamingException
- */
- protected Set<String> getRoleNamesForUser(String username,
- LdapContext ldapContext) throws NamingException {
-
- Set<String> roleNames = new LinkedHashSet<String>();
- SearchControls searchControls = createSearchControls();
- // set CN=username
- String SEARCH_FILTER = "(&(objectClass=*)(CN={0}))";
- Object[] SEARCH_ARGS = new Object[] { username };
- String searchBase = super.getUserDnSuffix();
- LOG.debug("searchBase=" + searchBase);
- NamingEnumeration<SearchResult> answer =
- ldapContext.search(searchBase, SEARCH_FILTER, SEARCH_ARGS,
- searchControls);
-
- String MEMBER_OF = "memberOf";
- while (answer.hasMoreElements()) {
- SearchResult searchResult = answer.next();
- Attributes attrs = searchResult.getAttributes();
- if (attrs != null) {
- NamingEnumeration<? extends Attribute> ae = attrs.getAll();
- while (ae.hasMore()) {
- Attribute attr = ae.next();
- if (attr.getID().equals(MEMBER_OF)) {
- Collection<String> groupNames = LdapUtils.getAllAttributeValues(attr);
- Collection<String> rolesForGroups = groupNames;
- roleNames.addAll(rolesForGroups);
- }
+
+ /**
+ * extracts a username from <code>principals</code>
+ *
+ * @param principals
+ * @return
+ * @throws ClassCastException
+ * the PrincipalCollection contains an element that is not in
+ * username/password form (i.e., X.509 certificate)
+ */
+ protected String getUsername(final PrincipalCollection principals)
+ throws ClassCastException {
+
+ if (null == principals) {
+ return null;
+ }
+ return (String) getAvailablePrincipal(principals);
+ }
+
+ @Override
+ protected AuthorizationInfo queryForAuthorizationInfo(
+ PrincipalCollection principals,
+ LdapContextFactory ldapContextFactory) throws NamingException {
+
+ AuthorizationInfo authorizationInfo = null;
+ try {
+ final String username = getUsername(principals);
+ LdapContext ldapContext = ldapContextFactory.getSystemLdapContext();
+ Set<String> roleNames;
+
+ try {
+ roleNames = getRoleNamesForUser(username, ldapContext);
+ authorizationInfo = buildAuthorizationInfo(roleNames);
+ } finally {
+ LdapUtils.closeContext(ldapContext);
+ }
+ } catch (ClassCastException e) {
+ final String ERROR_MESSAGE = "Unable to extract a valid user";
+ LOG.error(ERROR_MESSAGE, e);
}
- }
+ return authorizationInfo;
+ }
+
+ public static AuthorizationInfo buildAuthorizationInfo(
+ final Set<String> roleNames) {
+ if (null == roleNames) {
+ return null;
+ }
+ return new SimpleAuthorizationInfo(roleNames);
+ }
+
+ /**
+ * extracts the Set of roles associated with a user based on the username
+ * and ldap context (server).
+ *
+ * @param username
+ * @param ldapContext
+ * @return
+ * @throws NamingException
+ */
+ protected Set<String> getRoleNamesForUser(String username,
+ LdapContext ldapContext) throws NamingException {
+
+ Set<String> roleNames = new LinkedHashSet<String>();
+ SearchControls searchControls = createSearchControls();
+ // set CN=username
+ String SEARCH_FILTER = "(&(objectClass=*)(CN={0}))";
+ Object[] SEARCH_ARGS = new Object[] { username };
+ String searchBase = super.getUserDnSuffix();
+ final String DEBUG_MESSAGE = searchBase=" + searchBase";
+ LOG.debug(DEBUG_MESSAGE);
+ NamingEnumeration<SearchResult> answer = ldapContext.search(searchBase,
+ SEARCH_FILTER, SEARCH_ARGS, searchControls);
+
+ String MEMBER_OF = "memberOf";
+ while (answer.hasMoreElements()) {
+ SearchResult searchResult = answer.next();
+ Attributes attrs = searchResult.getAttributes();
+ if (attrs != null) {
+ NamingEnumeration<? extends Attribute> ae = attrs.getAll();
+ while (ae.hasMore()) {
+ Attribute attr = ae.next();
+ if (attr.getID().equals(MEMBER_OF)) {
+ Collection<String> groupNames = LdapUtils
+ .getAllAttributeValues(attr);
+ Collection<String> rolesForGroups = groupNames;
+ roleNames.addAll(rolesForGroups);
+ }
+ }
+ }
+ }
+ return roleNames;
+ }
+
+ /**
+ * A utility method to help create the search controls for the LDAP lookup
+ *
+ * @return
+ */
+ protected static SearchControls createSearchControls() {
+ SearchControls searchControls = new SearchControls();
+ searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+ return searchControls;
+ }
+
+ public String getUserDnSuffix() {
+ return super.getUserDnSuffix();
}
- return roleNames;
- }
-
- /**
- * A utility method to help create the search controls for the LDAP lookup
- *
- * @return
- */
- protected static SearchControls createSearchControls() {
- SearchControls searchControls = new SearchControls();
- searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
- return searchControls;
- }
-
- public String getUserDnSuffix() {
- return super.getUserDnSuffix();
- }
}
/**
* Implementation of a Radius AuthorizingRealm.
*
- *
* @author Ryan Goulding (ryandgoulding@gmail.com)
*/
public class RadiusRealm extends AuthorizingRealm {
- @Override
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
- // TODO use JRadius to extract Authorization Info
- return null;
- }
+ @Override
+ protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
+ // TODO use JRadius to extract Authorization Info
+ return null;
+ }
- @Override
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0)
- throws AuthenticationException {
- // TODO use JRadius to extract Authentication Info
- return null;
- }
+ @Override
+ protected AuthenticationInfo doGetAuthenticationInfo(
+ AuthenticationToken arg0) throws AuthenticationException {
+ // TODO use JRadius to extract Authentication Info
+ return null;
+ }
}
*/
public class TACACSRealm extends AuthorizingRealm {
- @Override
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
- // TODO Extract AuthorizationInfo using JNetLib
- return null;
- }
+ @Override
+ protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
+ // TODO Extract AuthorizationInfo using JNetLib
+ return null;
+ }
- @Override
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0)
- throws AuthenticationException {
- // TODO Extract AuthenticationInfo using JNetLib
- return null;
- }
+ @Override
+ protected AuthenticationInfo doGetAuthenticationInfo(
+ AuthenticationToken arg0) throws AuthenticationException {
+ // TODO Extract AuthenticationInfo using JNetLib
+ return null;
+ }
}
*/
public class KarafIniWebEnvironment extends IniWebEnvironment {
- private static Logger LOG = LoggerFactory.getLogger(KarafIniWebEnvironment.class);
- public static final String DEFAULT_SHIRO_INI_FILE = "etc/shiro.ini";
- public static final String SHIRO_FILE_PREFIX = "file:/";
+ private static final Logger LOG = LoggerFactory
+ .getLogger(KarafIniWebEnvironment.class);
+ public static final String DEFAULT_SHIRO_INI_FILE = "etc/shiro.ini";
+ public static final String SHIRO_FILE_PREFIX = "file:/";
- public KarafIniWebEnvironment() {
- }
+ public KarafIniWebEnvironment() {
+ }
- @Override
- public void init() {
- // Initialize the Shiro environment from etc/shiro.ini then delegate to the
- // parent class
- Ini ini;
- try {
- ini = createDefaultShiroIni();
- setIni(ini);
- } catch (FileNotFoundException e) {
- final String ERROR_MESSAGE = "Could not find etc/shiro.ini";
- LOG.error(ERROR_MESSAGE, e);
+ @Override
+ public void init() {
+ // Initialize the Shiro environment from etc/shiro.ini then delegate to
+ // the
+ // parent class
+ Ini ini;
+ try {
+ ini = createDefaultShiroIni();
+ setIni(ini);
+ } catch (FileNotFoundException e) {
+ final String ERROR_MESSAGE = "Could not find etc/shiro.ini";
+ LOG.error(ERROR_MESSAGE, e);
+ }
+ super.init();
}
- super.init();
- }
- /**
- *
- * @return Ini associated with <code>$KARAF_HOME/etc/shiro.ini</code>
- * @throws FileNotFoundException
- */
- static Ini createDefaultShiroIni() throws FileNotFoundException {
- return createShiroIni(DEFAULT_SHIRO_INI_FILE);
- }
+ /**
+ *
+ * @return Ini associated with <code>$KARAF_HOME/etc/shiro.ini</code>
+ * @throws FileNotFoundException
+ */
+ static Ini createDefaultShiroIni() throws FileNotFoundException {
+ return createShiroIni(DEFAULT_SHIRO_INI_FILE);
+ }
- /**
- *
- * @param path the file path, which is either absolute or relative to
- * <code>$KARAF_HOME</code>
- * @return Ini loaded from <code>path</code>
- */
- static Ini createShiroIni(final String path) throws FileNotFoundException {
- File f = new File(path);
- Ini ini = new Ini();
- final String fileBasedIniPath = createFileBasedIniPath(f.getAbsolutePath());
- ini.loadFromPath(fileBasedIniPath);
- return ini;
- }
+ /**
+ *
+ * @param path
+ * the file path, which is either absolute or relative to
+ * <code>$KARAF_HOME</code>
+ * @return Ini loaded from <code>path</code>
+ */
+ static Ini createShiroIni(final String path) throws FileNotFoundException {
+ File f = new File(path);
+ Ini ini = new Ini();
+ final String fileBasedIniPath = createFileBasedIniPath(f
+ .getAbsolutePath());
+ ini.loadFromPath(fileBasedIniPath);
+ return ini;
+ }
- /**
- *
- * @param path the file path, which is either absolute or relative to
- * <code>$KARAF_HOME</code>
- * @return <code>file:/$KARAF_HOME/etc/shiro.ini</code>
- */
- static String createFileBasedIniPath(final String path) {
- String fileBasedIniPath = SHIRO_FILE_PREFIX + path;
- LOG.debug(fileBasedIniPath);
- return fileBasedIniPath;
- }
+ /**
+ *
+ * @param path
+ * the file path, which is either absolute or relative to
+ * <code>$KARAF_HOME</code>
+ * @return <code>file:/$KARAF_HOME/etc/shiro.ini</code>
+ */
+ static String createFileBasedIniPath(final String path) {
+ String fileBasedIniPath = SHIRO_FILE_PREFIX + path;
+ LOG.debug(fileBasedIniPath);
+ return fileBasedIniPath;
+ }
}
--- /dev/null
+/*
+ * 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.*;
+
+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());
+ }
+}
package org.opendaylight.aaa.shiro.realm;
-import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
import java.util.Collection;
import java.util.HashSet;
*/
public class ODLJndiLdapRealmTest {
- /**
- * throw-away anonymous test class
- */
- class TestNamingEnumeration implements NamingEnumeration<SearchResult> {
-
- /**
- * state variable
- */
- boolean first = true;
-
- /**
- * returned the first time <code>next()</code> or
- * <code>nextElement()</code> is called.
- */
- SearchResult searchResult = new SearchResult("testuser",
- null, new BasicAttributes("memberOf", "engineering"));
-
/**
- * returns true the first time, then false for subsequent calls
+ * throw-away anonymous test class
*/
- @Override
- public boolean hasMoreElements() {
- return first;
- }
-
- /**
- * returns <code>searchResult</code> 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 {
- }
+ class TestNamingEnumeration implements NamingEnumeration<SearchResult> {
+
+ /**
+ * state variable
+ */
+ boolean first = true;
+
+ /**
+ * returned the first time <code>next()</code> or
+ * <code>nextElement()</code> is called.
+ */
+ SearchResult searchResult = new SearchResult("testuser", null,
+ new BasicAttributes("memberOf", "engineering"));
+
+ /**
+ * returns true the first time, then false for subsequent calls
+ */
+ @Override
+ public boolean hasMoreElements() {
+ return first;
+ }
+
+ /**
+ * returns <code>searchResult</code> 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 <code>searchResult</code> then null for subsequent calls
+ */
+ @Override
+ public SearchResult next() throws NamingException {
+ if (first) {
+ first = false;
+ return searchResult;
+ }
+ return null;
+ }
+ };
/**
- * returns true the first time, then false for subsequent calls
- */
- @Override
- public boolean hasMore() throws NamingException {
- return first;
- }
-
- /**
- * returns <code>searchResult</code> then null for subsequent calls
+ * throw away test class
+ *
+ * @author ryan
*/
- @Override
- public SearchResult next() throws NamingException {
- if(first) {
- first = false;
- return searchResult;
- }
- return null;
- }
- };
-
- /**
- * throw away test class
- *
- * @author ryan
- */
- class TestPrincipalCollection implements PrincipalCollection {
- /**
+ class TestPrincipalCollection implements PrincipalCollection {
+ /**
*
*/
- private static final long serialVersionUID = -1236759619455574475L;
-
- Vector<String> collection =
- new Vector<String>();
-
- public TestPrincipalCollection(String element) {
- collection.add(element);
- }
-
- @Override
- public Iterator<String> iterator() {
- return collection.iterator();
- }
-
- @Override
- public List<String> asList() {
- return collection;
- }
-
- @Override
- public Set<String> asSet() {
- HashSet<String> set = new HashSet<String>();
- set.addAll(collection);
- return set;
- }
-
- @Override
- public <T> Collection<T> byType(Class<T> arg0) {
- return null;
+ private static final long serialVersionUID = -1236759619455574475L;
+
+ Vector<String> collection = new Vector<String>();
+
+ public TestPrincipalCollection(String element) {
+ collection.add(element);
+ }
+
+ @Override
+ public Iterator<String> iterator() {
+ return collection.iterator();
+ }
+
+ @Override
+ public List<String> asList() {
+ return collection;
+ }
+
+ @Override
+ public Set<String> asSet() {
+ HashSet<String> set = new HashSet<String>();
+ set.addAll(collection);
+ return set;
+ }
+
+ @Override
+ public <T> Collection<T> byType(Class<T> arg0) {
+ return null;
+ }
+
+ @Override
+ public Collection<String> fromRealm(String arg0) {
+ return collection;
+ }
+
+ @Override
+ public Object getPrimaryPrincipal() {
+ return collection.firstElement();
+ }
+
+ @Override
+ public Set<String> getRealmNames() {
+ return null;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return collection.isEmpty();
+ }
+
+ @Override
+ public <T> T oneByType(Class<T> 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));
}
- @Override
- public Collection<String> fromRealm(String arg0) {
- return collection;
+ @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);
}
- @Override
- public Object getPrimaryPrincipal() {
- return collection.firstElement();
+ @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(),
+ (Object[]) 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"));
}
- @Override
- public Set<String> getRealmNames() {
- return null;
+ @Test
+ public void testBuildAuthorizationInfo() {
+ assertNull(ODLJndiLdapRealm.buildAuthorizationInfo(null));
+ Set<String> roleNames = new HashSet<String>();
+ roleNames.add("engineering");
+ AuthorizationInfo authorizationInfo = ODLJndiLdapRealm
+ .buildAuthorizationInfo(roleNames);
+ assertNotNull(authorizationInfo);
+ assertFalse(authorizationInfo.getRoles().isEmpty());
+ assertTrue(authorizationInfo.getRoles().contains("engineering"));
}
- @Override
- public boolean isEmpty() {
- return collection.isEmpty();
+ @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(),
+ (Object[]) any(), (SearchControls) any())).thenReturn(
+ new TestNamingEnumeration());
+
+ // extracts the roles for "testuser" and ensures engineering is returned
+ Set<String> roles = ldapRealm.getRoleNamesForUser("testuser",
+ ldapContext);
+ assertFalse(roles.isEmpty());
+ assertTrue(roles.iterator().next().equals("engineering"));
}
- @Override
- public <T> T oneByType(Class<T> arg0) {
- // TODO Auto-generated method stub
- return null;
+ @Test
+ public void testCreateSearchControls() {
+ SearchControls searchControls = ODLJndiLdapRealm.createSearchControls();
+ assertNotNull(searchControls);
+ int expectedSearchScope = SearchControls.SUBTREE_SCOPE;
+ int actualSearchScope = searchControls.getSearchScope();
+ assertEquals(expectedSearchScope, actualSearchScope);
}
- };
-
- @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(), (Object[]) 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<String> roleNames = new HashSet<String>();
- 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(), (Object[]) any(),
- (SearchControls) any()))
- .thenReturn(new TestNamingEnumeration());
-
- // extracts the roles for "testuser" and ensures engineering is returned
- Set<String> 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);
- }
}
* @author Ryan Goulding (ryandgoulding@gmail.com)
*/
public class KarafIniWebEnvironmentTest {
- private static File iniFile;
+ private static File iniFile;
- @BeforeClass
- public static void setup() throws IOException {
- iniFile = createShiroIniFile();
- assertTrue(iniFile.exists());
- }
+ @BeforeClass
+ public static void setup() throws IOException {
+ iniFile = createShiroIniFile();
+ assertTrue(iniFile.exists());
+ }
- @AfterClass
- public static void teardown() {
- iniFile.delete();
- }
+ @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 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;
- }
+ 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 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);
- }
+ @Test
+ public void testCreateFileBasedIniPath() {
+ String testPath = "/shiro.ini";
+ String expectedFileBasedIniPath = KarafIniWebEnvironment.SHIRO_FILE_PREFIX
+ + testPath;
+ String actualFileBasedIniPath = KarafIniWebEnvironment
+ .createFileBasedIniPath(testPath);
+ assertEquals(expectedFileBasedIniPath, actualFileBasedIniPath);
+ }
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>features-mdsal</artifactId>
- <version>${mdsal.version}</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>features-mdsal</artifactId>
- <version>${mdsal.model.version}</version>
<classifier>features</classifier>
<type>xml</type>
</dependency>
<dependencies>
<dependency>
<groupId>org.opendaylight.aaa</groupId>
- <artifactId>features-aaa-api</artifactId>
- <classifier>features</classifier>
- <type>xml</type>
+ <artifactId>aaa-shiro-act</artifactId>
+ <version>0.3.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.aaa</groupId>
<artifactId>aaa-shiro</artifactId>
<version>0.3.0-SNAPSHOT</version>
+ <type>cfg</type>
+ <classifier>configuration</classifier>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.aaa</groupId>
+ <artifactId>aaa-shiro</artifactId>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<features name="odl-aaa-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
- <repository>mvn:org.opendaylight.aaa/features-aaa-api/${project.version}/xml/features</repository>
+ <!-- odl-aaa-shiro feature which combines all aspects of AAA into one feature -->
<feature name='odl-aaa-shiro' description='OpenDaylight :: AAA :: Shiro'
- version='${project.version}'>
+ version='0.3.0-SNAPSHOT'>
<!-- OSGI -->
<bundle>mvn:org.apache.felix/org.apache.felix.dependencymanager/{{VERSION}}</bundle>
<bundle>mvn:org.apache.felix/org.apache.felix.metatype/{{VERSION}}</bundle>
<!-- Apache Shiro & Dependencies -->
<bundle>mvn:org.apache.shiro/shiro-core/1.2.3</bundle>
<bundle>mvn:org.apache.shiro/shiro-web/1.2.3</bundle>
- <bundle>wrap:mvn:javax.servlet/javax.servlet-api/3.1.0</bundle>
+ <bundle>wrap:mvn:javax.servlet/servlet-api/2.5</bundle>
+ <!-- AAA bundles relating to stand-alone shiro feature -->
+ <configfile finalname="/etc/shiro.ini">mvn:org.opendaylight.aaa/aaa-shiro/{{VERSION}}/cfg/configuration</configfile>
<bundle>mvn:org.opendaylight.aaa/aaa-shiro/{{VERSION}}</bundle>
+ <bundle>mvn:org.opendaylight.aaa/aaa-shiro-act/{{VERSION}}</bundle>
</feature>
</features>
<module>distribution-karaf</module>
<module>parent</module>
<module>aaa-shiro</module>
+ <module>aaa-shiro-act</module>
</modules>
<scm>