Add aaa-authn-odl-plugin 35/26335/2
authorTomas Cere <tcere@cisco.com>
Wed, 2 Sep 2015 09:39:22 +0000 (11:39 +0200)
committerTomas Cere <tcere@cisco.com>
Thu, 3 Sep 2015 08:26:51 +0000 (08:26 +0000)
Move in aaa-authn-odl-plugin to prevent cyclic dependency between
aaa and netconf.

Change-Id: Ibb89231b229664bbc9ae6d97c098f637de764448
Signed-off-by: Tomas Cere <tcere@cisco.com>
features/netconf/pom.xml
features/netconf/src/main/resources/features.xml
opendaylight/netconf/aaa-authn-odl-plugin/pom.xml [new file with mode: 0644]
opendaylight/netconf/aaa-authn-odl-plugin/src/main/java/org/opendaylight/aaa/odl/CredentialServiceAuthProvider.java [new file with mode: 0644]
opendaylight/netconf/aaa-authn-odl-plugin/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/netconf/plugin/rev150715/AuthProviderModule.java [new file with mode: 0644]
opendaylight/netconf/aaa-authn-odl-plugin/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/netconf/plugin/rev150715/AuthProviderModuleFactory.java [new file with mode: 0644]
opendaylight/netconf/aaa-authn-odl-plugin/src/main/yang/aaa-authn-netconf-plugin.yang [new file with mode: 0644]
opendaylight/netconf/aaa-authn-odl-plugin/src/test/java/org/opendaylight/aaa/odl/CredentialServiceAuthProviderTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-artifacts/pom.xml
opendaylight/netconf/pom.xml

index 0e7e2c694241aafd4dc7937c8da9fb0e815c5d1e..4f7dbecdd4e15bbfaa481c9f73064c21b4cdfea6 100644 (file)
       <type>xml</type>
       <scope>runtime</scope>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>aaa-authn-odl-plugin</artifactId>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-api</artifactId>
index e561c45cff4f39b40262d1638d9b61db377a3a0b..0db66c6d0a5b25ec174667aea74fceb0727598b9 100644 (file)
     <!-- FIXME: This introduces cycle between projects, which makes version updates
                 harder. Should be moved to different.
     -->
-    <feature version='${aaa.version}'>odl-aaa-netconf-plugin</feature>
+    <feature version='${project.version}'>odl-aaa-netconf-plugin</feature>
     <bundle>mvn:org.opendaylight.netconf/netconf-ssh/${project.version}</bundle>
   </feature>
 
     <bundle>mvn:org.opendaylight.netconf/mdsal-netconf-monitoring/${project.version}</bundle>
     <configfile finalname='${config.configfile.directory}/${config.netconf.mdsal.configfile}'>mvn:org.opendaylight.netconf/netconf-mdsal-config/${project.version}/xml/config</configfile>
   </feature>
+
+  <feature name='odl-aaa-netconf-plugin' description='OpenDaylight :: AAA :: ODL NETCONF Plugin'
+           version='${project.version}'>
+    <feature version='${config.version}'>odl-config-api</feature>
+    <bundle>mvn:org.opendaylight.netconf/netconf-auth/${project.version}</bundle>
+    <feature version='${aaa.version}'>odl-aaa-authn</feature>
+    <bundle>mvn:org.opendaylight.netconf/aaa-authn-odl-plugin/${project.version}</bundle>
+  </feature>
+
+  <feature name='odl-aaa-netconf-plugin-no-cluster'
+           description='OpenDaylight :: AAA :: ODL NETCONF Plugin - NO CLUSTER'
+           version='${project.version}'>
+    <feature version='${config.version}'>odl-config-api</feature>
+    <bundle>mvn:org.opendaylight.netconf/netconf-auth/${project.version}</bundle>
+    <feature version='${aaa.version}'>odl-aaa-authn-no-cluster</feature>
+    <bundle>mvn:org.opendaylight.netconf/aaa-authn-odl-plugin/${project.version}</bundle>
+  </feature>
 </features>
diff --git a/opendaylight/netconf/aaa-authn-odl-plugin/pom.xml b/opendaylight/netconf/aaa-authn-odl-plugin/pom.xml
new file mode 100644 (file)
index 0000000..b246556
--- /dev/null
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2015 Cisco 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.netconf</groupId>
+        <artifactId>netconf-subsystem</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <artifactId>aaa-authn-odl-plugin</artifactId>
+    <packaging>bundle</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.aaa</groupId>
+            <artifactId>aaa-authn-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>netconf-auth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <!-- Testing Dependencies -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yang-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/opendaylight/netconf/aaa-authn-odl-plugin/src/main/java/org/opendaylight/aaa/odl/CredentialServiceAuthProvider.java b/opendaylight/netconf/aaa-authn-odl-plugin/src/main/java/org/opendaylight/aaa/odl/CredentialServiceAuthProvider.java
new file mode 100644 (file)
index 0000000..8d2350e
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2013 Cisco 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.odl;
+
+import java.util.Map;
+import org.opendaylight.aaa.api.AuthenticationException;
+import org.opendaylight.aaa.api.Claim;
+import org.opendaylight.aaa.api.CredentialAuth;
+import org.opendaylight.aaa.api.PasswordCredentials;
+import org.opendaylight.netconf.auth.AuthProvider;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * AuthProvider implementation delegating to AAA CredentialAuth&lt;PasswordCredentials&gt; instance.
+ */
+public final class CredentialServiceAuthProvider implements AuthProvider, AutoCloseable {
+    private static final Logger logger = LoggerFactory.getLogger(CredentialServiceAuthProvider.class);
+
+    /**
+     * Singleton instance with delayed instantiation
+     */
+    public static volatile Map.Entry<BundleContext, CredentialServiceAuthProvider> INSTANCE;
+
+    // TODO what domain should be used for this ? can we leave null ?
+    public static final String DOMAIN = null;
+
+    // FIXME CredentialAuth is generic and it causes warnings during compilation
+    // Maybe there should be a PasswordCredentialAuth implements CredentialAuth<PasswordCredentials>
+    private volatile CredentialAuth<PasswordCredentials> nullableCredService;
+    private final ServiceTracker<CredentialAuth, CredentialAuth> listenerTracker;
+
+    public CredentialServiceAuthProvider(final BundleContext bundleContext) {
+
+        final ServiceTrackerCustomizer<CredentialAuth, CredentialAuth> customizer = new ServiceTrackerCustomizer<CredentialAuth, CredentialAuth>() {
+            @Override
+            public CredentialAuth addingService(final ServiceReference<CredentialAuth> reference) {
+                logger.trace("Credential service {} added", reference);
+                nullableCredService = bundleContext.getService(reference);
+                return nullableCredService;
+            }
+
+            @Override
+            public void modifiedService(final ServiceReference<CredentialAuth> reference, final CredentialAuth service) {
+                logger.trace("Replacing modified Credential service {}", reference);
+                nullableCredService = service;
+            }
+
+            @Override
+            public void removedService(final ServiceReference<CredentialAuth> reference, final CredentialAuth service) {
+                logger.trace("Removing Credential service {}. This AuthProvider will fail to authenticate every time", reference);
+                synchronized (CredentialServiceAuthProvider.this) {
+                    nullableCredService = null;
+                }
+            }
+        };
+        listenerTracker = new ServiceTracker<>(bundleContext, CredentialAuth.class, customizer);
+        listenerTracker.open();
+    }
+
+    /**
+     * Authenticate user. This implementation tracks CredentialAuth<PasswordCredentials> and delegates the decision to it. If the service is not
+     * available, IllegalStateException is thrown.
+     */
+    @Override
+    public synchronized boolean authenticated(final String username, final String password) {
+        if (nullableCredService == null) {
+            logger.warn("Cannot authenticate user '{}', Credential service is missing", username);
+            throw new IllegalStateException("Credential service is not available");
+        }
+
+        Claim claim;
+        try {
+            claim = nullableCredService.authenticate(new PasswordCredentialsWrapper(username, password), DOMAIN);
+        } catch (AuthenticationException e) {
+            logger.debug("Authentication failed for user '{}' : {}", username, e);
+            return false;
+        }
+
+        logger.debug("Authentication result for user '{}' : {}", username, claim.domain());
+        return true;
+    }
+
+    @Override
+    public void close() throws Exception {
+        listenerTracker.close();
+        nullableCredService = null;
+    }
+
+    private static final class PasswordCredentialsWrapper implements PasswordCredentials {
+        private final String username;
+        private final String password;
+
+        public PasswordCredentialsWrapper(final String username, final String password) {
+            this.username = username;
+            this.password = password;
+        }
+
+        @Override
+        public String username() {
+            return username;
+        }
+
+        @Override
+        public String password() {
+            return password;
+        }
+    }
+}
diff --git a/opendaylight/netconf/aaa-authn-odl-plugin/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/netconf/plugin/rev150715/AuthProviderModule.java b/opendaylight/netconf/aaa-authn-odl-plugin/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/netconf/plugin/rev150715/AuthProviderModule.java
new file mode 100644 (file)
index 0000000..e264881
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015 Cisco 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.yang.gen.v1.config.aaa.authn.netconf.plugin.rev150715;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.aaa.odl.CredentialServiceAuthProvider;
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.osgi.framework.BundleContext;
+
+public class AuthProviderModule extends org.opendaylight.yang.gen.v1.config.aaa.authn.netconf.plugin.rev150715.AbstractAuthProviderModule {
+
+    private BundleContext bundleContext;
+
+    public AuthProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public AuthProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.config.aaa.authn.netconf.plugin.rev150715.AuthProviderModule oldModule, AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    public AuthProviderModule(final ModuleIdentifier moduleIdentifier, final DependencyResolver dependencyResolver, final AuthProviderModule oldModule, final AutoCloseable oldInstance, final BundleContext bundleContext) {
+        this(moduleIdentifier, dependencyResolver, oldModule, oldInstance);
+        this.bundleContext = bundleContext;
+    }
+
+    public AuthProviderModule(final ModuleIdentifier moduleIdentifier, final DependencyResolver dependencyResolver, final BundleContext bundleContext) {
+        this(moduleIdentifier, dependencyResolver);
+        this.bundleContext = bundleContext;
+    }
+
+    @Override
+    public void customValidation() {
+        Preconditions.checkNotNull(bundleContext, "BundleContext was not properly set up");
+    }
+
+    @Override
+    public AutoCloseable createInstance() {
+       return new CredentialServiceAuthProvider(bundleContext);
+    }
+
+}
diff --git a/opendaylight/netconf/aaa-authn-odl-plugin/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/netconf/plugin/rev150715/AuthProviderModuleFactory.java b/opendaylight/netconf/aaa-authn-odl-plugin/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/netconf/plugin/rev150715/AuthProviderModuleFactory.java
new file mode 100644 (file)
index 0000000..495ac42
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015 Cisco 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
+ */
+
+/*
+* Generated file
+*
+* Generated from: yang module name: aaa-authn-netconf-plugin yang module local name: aaa-authn-netconf-plugin
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Jul 15 15:16:51 CEST 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.config.aaa.authn.netconf.plugin.rev150715;
+
+import java.util.Collections;
+import java.util.Set;
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DependencyResolverFactory;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.osgi.framework.BundleContext;
+
+public class AuthProviderModuleFactory extends org.opendaylight.yang.gen.v1.config.aaa.authn.netconf.plugin.rev150715.AbstractAuthProviderModuleFactory {
+
+    private static final ModuleIdentifier DEFAULT_INSTANCE_ID = new ModuleIdentifier(NAME, "default-auth-provider");
+
+    @Override
+    public AuthProviderModule instantiateModule(final String instanceName, final DependencyResolver dependencyResolver, final AuthProviderModule oldModule, final AutoCloseable oldInstance, final BundleContext bundleContext) {
+        return new AuthProviderModule(
+                new ModuleIdentifier(NAME, instanceName), dependencyResolver, oldModule, oldInstance, bundleContext);
+    }
+
+    @Override
+    public AuthProviderModule instantiateModule(final String instanceName, final DependencyResolver dependencyResolver, final BundleContext bundleContext) {
+        return new AuthProviderModule(
+                new ModuleIdentifier(NAME, instanceName), dependencyResolver, bundleContext);
+    }
+
+    @Override
+    public Set<AuthProviderModule> getDefaultModules(final DependencyResolverFactory dependencyResolverFactory, final BundleContext bundleContext) {
+        // Config subsystem puts this instance into OSGi service registry automatically
+        final DependencyResolver dependencyResolver = dependencyResolverFactory.createDependencyResolver(DEFAULT_INSTANCE_ID);
+        return Collections.singleton(new AuthProviderModule(DEFAULT_INSTANCE_ID, dependencyResolver, bundleContext));
+    }
+}
diff --git a/opendaylight/netconf/aaa-authn-odl-plugin/src/main/yang/aaa-authn-netconf-plugin.yang b/opendaylight/netconf/aaa-authn-odl-plugin/src/main/yang/aaa-authn-netconf-plugin.yang
new file mode 100644 (file)
index 0000000..ffa6d98
--- /dev/null
@@ -0,0 +1,27 @@
+module aaa-authn-netconf-plugin {
+
+    yang-version 1;
+    namespace "config:aaa:authn:netconf:plugin";
+    prefix "aaa-authn-store-cfg";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import netconf-auth { prefix na; revision-date 2015-07-15; }
+
+    revision "2015-07-15" {
+        description
+            "Initial revision.";
+    }
+
+    identity aaa-authn-netconf-plugin {
+            base config:module-type;
+            config:java-name-prefix AuthProvider;
+            config:provided-service na:netconf-auth-provider;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case aaa-authn-netconf-plugin {
+            when "/config:modules/config:module/config:type = 'aaa-authn-netconf-plugin'";
+            // no config yet
+       }
+    }
+}
diff --git a/opendaylight/netconf/aaa-authn-odl-plugin/src/test/java/org/opendaylight/aaa/odl/CredentialServiceAuthProviderTest.java b/opendaylight/netconf/aaa-authn-odl-plugin/src/test/java/org/opendaylight/aaa/odl/CredentialServiceAuthProviderTest.java
new file mode 100644 (file)
index 0000000..5f9bbfe
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2014, 2015 Cisco 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.odl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.opendaylight.aaa.api.AuthenticationException;
+import org.opendaylight.aaa.api.Claim;
+import org.opendaylight.aaa.api.CredentialAuth;
+import org.opendaylight.aaa.api.PasswordCredentials;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+public class CredentialServiceAuthProviderTest {
+
+    @Mock
+    private CredentialAuth<PasswordCredentials> credAuth;
+    @Mock
+    private BundleContext ctx;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        doReturn(mock(Filter.class)).when(ctx).createFilter(anyString());
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testAuthenticatedNoDelegate() throws Exception {
+        CredentialServiceAuthProvider credentialServiceAuthProvider = new CredentialServiceAuthProvider(ctx);
+        credentialServiceAuthProvider.authenticated("user", "pwd");
+    }
+
+    @Test
+    public void testAuthenticatedTrue() throws Exception {
+        ServiceReference serviceRef = mock(ServiceReference.class);
+
+        ServiceListenerAnswer answer = new ServiceListenerAnswer();
+        doAnswer(answer).when(ctx).addServiceListener(any(ServiceListener.class), anyString());
+
+        Claim claim = mock(Claim.class);
+        doReturn("domain").when(claim).domain();
+        doReturn(claim).when(credAuth).authenticate(any(PasswordCredentials.class), anyString());
+
+        doReturn(credAuth).when(ctx).getService(serviceRef);
+        CredentialServiceAuthProvider credentialServiceAuthProvider = new CredentialServiceAuthProvider(ctx);
+
+        answer.serviceListener.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, serviceRef));
+        assertNotNull(answer.serviceListener);
+
+        assertTrue(credentialServiceAuthProvider.authenticated("user", "pwd"));
+    }
+
+    @Test
+    public void testAuthenticatedFalse() throws Exception {
+        ServiceReference serviceRef = mock(ServiceReference.class);
+
+        ServiceListenerAnswer answer = new ServiceListenerAnswer();
+        doAnswer(answer).when(ctx).addServiceListener(any(ServiceListener.class), anyString());
+
+        doThrow(AuthenticationException.class).when(credAuth).authenticate(any(PasswordCredentials.class), anyString());
+
+        doReturn(credAuth).when(ctx).getService(serviceRef);
+        CredentialServiceAuthProvider credentialServiceAuthProvider = new CredentialServiceAuthProvider(ctx);
+
+        answer.serviceListener.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, serviceRef));
+        assertNotNull(answer.serviceListener);
+
+        assertFalse(credentialServiceAuthProvider.authenticated("user", "pwd"));
+    }
+
+    private static class ServiceListenerAnswer implements Answer {
+
+        ServiceListener serviceListener;
+
+        @Override
+        public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
+            serviceListener = (ServiceListener) invocationOnMock.getArguments()[0];
+            return null;
+        }
+    }
+}
index 51e3038d000d6e7f74d09ceca9bae30c7e8d4f36..50ceafd4cd74c7a273cc1aca26f75fef858c02ad 100644 (file)
 
     <dependencyManagement>
         <dependencies>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>aaa-authn-odl-plugin</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>netconf-config-dispatcher</artifactId>
index 7f382832a383e906f6ed6326d491a2b2f2979805..b2d5e2a77373f1eb5a39cc24e10ecdb9343533da 100644 (file)
@@ -31,6 +31,7 @@
     <module>netconf-connector-config</module>
     <module>netconf-mdsal-config</module>
     <module>netconf-auth</module>
+    <module>aaa-authn-odl-plugin</module>
     <module>netconf-notifications-impl</module>
     <module>netconf-notifications-api</module>
     <module>sal-netconf-connector</module>
 
   <dependencyManagement>
     <dependencies>
+      <dependency>
+        <groupId>org.opendaylight.aaa</groupId>
+        <artifactId>aaa-artifacts</artifactId>
+        <version>${aaa.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
       <dependency>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-artifacts</artifactId>