Refactor AAAShiroProvider & Co. to be non static 15/69415/6
authorMichael Vorburger <vorburger@redhat.com>
Mon, 12 Mar 2018 22:56:39 +0000 (23:56 +0100)
committerTom Pantelis <tompantelis@gmail.com>
Thu, 15 Mar 2018 15:09:31 +0000 (11:09 -0400)
- The IdmLightApplication is now instantiated and injected
  with the AAAShiroProvider and passed to the ServletContainer
  instead of the ServletContainer instantiating it via reflection.

- For KarafIniWebEnvironmentLoaderListener and KarafIniWebEnvironment,
  the initial plan was to inject the AAAShiroProvider however there
  are still web.xml files in ODL land that reference
  KarafIniWebEnvironment and expect a no-arg ctor. We need to keep
  backwards compatibility for a while so I'll follow-up later
  to add a new KarafIniWebEnvironmentLoaderListener that is advertised
  as a service for programmtic use. KarafIniWebEnvironment was changed
  to obtain the ShiroConfiguration statically rather than the
  AAAShiroProvider.

- The shiro lib still instantiates the filter/realm etc instances via
  reflection. These are specified via String key/value pairs with class names
  in the Ini instance. Unfortunately I see no way around this. So
  to avoid having to pass our services, eg DataBroker, via statics,
  I opted to use ThreadLocals to inject indirectly. This is a bit
  ugly but works.

Change-Id: I8f5114802c76cbd2b4bfda69952df2b28557cf8d
Signed-off-by: Michael Vorburger <vorburger@redhat.com>
Signed-off-by: Tom Pantelis <tompantelis@gmail.com>
32 files changed:
aaa-cli-jar/src/main/java/org/opendaylight/aaa/cli/jar/StandaloneCommandLineInterface.java
aaa-cli/src/main/java/org/opendaylight/aaa/cli/AaaCliAbstractCommand.java
aaa-cli/src/main/java/org/opendaylight/aaa/cli/dmstore/ChangeUserPassword.java
aaa-cli/src/main/resources/org/opendaylight/blueprint/commands.xml
aaa-shiro/impl/pom.xml
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/AAAShiroActivator.java [deleted file]
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/AAAShiroProvider.java
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/datastore/h2/H2Store.java
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/datastore/h2/IdmLightConfig.java
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/idm/DomainHandler.java
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/idm/IdmLightApplication.java
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/idm/IdmLightProxy.java
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/idm/RoleHandler.java
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/idm/UserHandler.java
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/realm/KeystoneAuthRealm.java
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/realm/MDSALDynamicAuthorizationFilter.java
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/realm/MdsalRealm.java
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/realm/ODLActiveDirectoryRealm.java
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/realm/ODLJndiLdapRealmAuthNOnly.java
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/web/env/KarafIniWebEnvironment.java
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/web/env/KarafIniWebEnvironmentLoaderListener.java
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/web/env/ThreadLocals.java [new file with mode: 0644]
aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/web/env/WebInitializer.java
aaa-shiro/impl/src/main/resources/initial/aaa-app-config.xml
aaa-shiro/impl/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml
aaa-shiro/impl/src/test/java/org/opendaylight/aaa/datastore/h2/DomainStoreTest.java
aaa-shiro/impl/src/test/java/org/opendaylight/aaa/datastore/h2/H2StoreTest.java
aaa-shiro/impl/src/test/java/org/opendaylight/aaa/datastore/h2/IdmLightConfigTest.java
aaa-shiro/impl/src/test/java/org/opendaylight/aaa/shiro/idm/persistence/PasswordHashTest.java
aaa-shiro/impl/src/test/java/org/opendaylight/aaa/shiro/idm/rest/test/HandlerTest.java
aaa-shiro/impl/src/test/java/org/opendaylight/aaa/shiro/realm/KeystoneAuthRealmTest.java
aaa-shiro/impl/src/test/java/org/opendaylight/aaa/shiro/realm/MDSALDynamicAuthorizationFilterTest.java

index d56f21d6aa68752ea70ef54397b229ca91d06a53..fdf859eaf962a7519e634dc6a979facf7e9ea3a8 100644 (file)
@@ -37,7 +37,7 @@ public class StandaloneCommandLineInterface {
 
     public StandaloneCommandLineInterface(File directoryWithDatabaseFile) throws IOException, IDMStoreException {
         IdmLightConfigBuilder configBuider = new IdmLightConfigBuilder();
-        configBuider.dbDirectory(directoryWithDatabaseFile.getCanonicalPath());
+        configBuider.dbDirectory(directoryWithDatabaseFile.getCanonicalPath()).dbUser("foo").dbPwd("bar");
         IdmLightConfig config = configBuider.build();
 
         H2Store h2Store = new H2Store(new IdmLightSimpleConnectionProvider(config));
index 89eef552763ff0e2e79fe909f871a0a93581ebda..2e7380c5a0b1dd1351466cd07f340ab5a6d20329 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.aaa.cli;
 
 import org.apache.karaf.shell.console.OsgiCommandSupport;
-import org.opendaylight.aaa.AAAShiroProvider;
 import org.opendaylight.aaa.api.IIDMStore;
 import org.opendaylight.aaa.api.model.User;
 import org.opendaylight.aaa.cli.utils.CliUtils;
@@ -23,10 +22,10 @@ import org.opendaylight.aaa.cli.utils.DataStoreUtils;
 public abstract class AaaCliAbstractCommand extends OsgiCommandSupport {
 
     private static volatile String authUser = null;
-    protected final IIDMStore identityStore;
+    protected IIDMStore identityStore;
 
-    public AaaCliAbstractCommand() {
-        this.identityStore = AAAShiroProvider.getIdmStore();
+    public void setIdentityStore(IIDMStore identityStore) {
+        this.identityStore = identityStore;
     }
 
     @Override
index bd08168a196a7c990bca8934f44d8efcc7cf2e62..b480544bc7bb3c47b261ab2cc27b9d75ab24ac31 100644 (file)
@@ -11,7 +11,6 @@ package org.opendaylight.aaa.cli.dmstore;
 import org.apache.karaf.shell.commands.Command;
 import org.apache.karaf.shell.commands.Option;
 import org.apache.karaf.shell.console.OsgiCommandSupport;
-import org.opendaylight.aaa.AAAShiroProvider;
 import org.opendaylight.aaa.api.IIDMStore;
 import org.opendaylight.aaa.api.SHA256Calculator;
 import org.opendaylight.aaa.api.model.User;
@@ -29,14 +28,14 @@ import org.opendaylight.aaa.shiro.idm.IdmLightProxy;
  */
 public class ChangeUserPassword extends OsgiCommandSupport {
 
-    protected IIDMStore identityStore;
+    private final IIDMStore identityStore;
 
     @Option(name = "-user", aliases = {
             "--userName" }, description = "The user name", required = true, multiValued = false)
-    private String userName = "";
+    private final String userName = "";
 
-    public ChangeUserPassword() {
-        this.identityStore = AAAShiroProvider.getIdmStore();
+    public ChangeUserPassword(IIDMStore identityStore) {
+        this.identityStore = identityStore;
     }
 
     @Override
index bb19e84777cd1a724e56109cda478596ef8d500e..970a3a38718dfb3d4a6f582e493b4412b30ab73e 100644 (file)
@@ -4,22 +4,28 @@
         activation="eager" interface="org.opendaylight.aaa.cert.api.ICertificateManager">
     </reference>
 
-    <reference id="iIDMStore" interface="org.opendaylight.aaa.api.IIDMStore"
-        availability="optional" timeout="30000">
-    </reference>
+    <reference id="iIDMStore" interface="org.opendaylight.aaa.api.IIDMStore" />
 
     <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
-            <action class="org.opendaylight.aaa.cli.dmstore.ListODLUsers" />
+            <action class="org.opendaylight.aaa.cli.dmstore.ListODLUsers">
+                <property name="identityStore" ref="iIDMStore"/>
+            </action>
         </command>
         <command>
-            <action class="org.opendaylight.aaa.cli.dmstore.ListODLDomains" />
+            <action class="org.opendaylight.aaa.cli.dmstore.ListODLDomains">
+                <property name="identityStore" ref="iIDMStore"/>
+            </action>
         </command>
         <command>
-            <action class="org.opendaylight.aaa.cli.dmstore.ListODLRoles" />
+            <action class="org.opendaylight.aaa.cli.dmstore.ListODLRoles">
+                <property name="identityStore" ref="iIDMStore"/>
+            </action>
         </command>
         <command>
-            <action class="org.opendaylight.aaa.cli.dmstore.ChangeUserPassword" />
+            <action class="org.opendaylight.aaa.cli.dmstore.ChangeUserPassword">
+                <argument ref="iIDMStore" />
+            </action>
         </command>
         <command>
             <action class="org.opendaylight.aaa.cli.cert.GetODLSelfSignCert">
             </action>
         </command>
         <command>
-            <action class="org.opendaylight.aaa.cli.dmstore.AddRole" />
+            <action class="org.opendaylight.aaa.cli.dmstore.AddRole">
+                <property name="identityStore" ref="iIDMStore"/>
+            </action>
         </command>
         <command>
-            <action class="org.opendaylight.aaa.cli.dmstore.AddDomain" />
+            <action class="org.opendaylight.aaa.cli.dmstore.AddDomain">
+                <property name="identityStore" ref="iIDMStore"/>
+            </action>
         </command>
         <command>
-            <action class="org.opendaylight.aaa.cli.dmstore.AddUser" />
+            <action class="org.opendaylight.aaa.cli.dmstore.AddUser">
+                <property name="identityStore" ref="iIDMStore"/>
+            </action>
         </command>
         <command>
-            <action class="org.opendaylight.aaa.cli.dmstore.AddGrant" />
+            <action class="org.opendaylight.aaa.cli.dmstore.AddGrant">
+                <property name="identityStore" ref="iIDMStore"/>
+            </action>
         </command>
         <command>
-            <action class="org.opendaylight.aaa.cli.dmstore.RemoveGrant" />
+            <action class="org.opendaylight.aaa.cli.dmstore.RemoveGrant">
+                <property name="identityStore" ref="iIDMStore"/>
+            </action>
         </command>
         <command>
-            <action class="org.opendaylight.aaa.cli.dmstore.RemoveUser" />
+            <action class="org.opendaylight.aaa.cli.dmstore.RemoveUser">
+                <property name="identityStore" ref="iIDMStore"/>
+            </action>
         </command>
         <command>
-            <action class="org.opendaylight.aaa.cli.dmstore.RemoveRole" />
+            <action class="org.opendaylight.aaa.cli.dmstore.RemoveRole">
+                <property name="identityStore" ref="iIDMStore"/>
+            </action>
         </command>
         <command>
-            <action class="org.opendaylight.aaa.cli.dmstore.RemoveDomain" />
+            <action class="org.opendaylight.aaa.cli.dmstore.RemoveDomain">
+                <property name="identityStore" ref="iIDMStore"/>
+            </action>
         </command>
     </command-bundle>
 
-</blueprint>
\ No newline at end of file
+</blueprint>
index 95121320f16f92ff06ff116fa2e3415306e1956c..33e636cfe57175671cbdc9ec083cef5aa4f1ac80 100644 (file)
@@ -120,10 +120,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.compendium</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.core</artifactId>
-        </dependency>
 
         <!-- JSON JAXB Stuff -->
         <dependency>
@@ -243,8 +239,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
                         <Import-Package>
                             com.google.*,
                             com.sun.jersey.spi.container.servlet,
+                            com.sun.jersey.api.client.config,
                             javax.servlet.http,
                             javax.servlet.*,
+                            javax.net.ssl,
                             org.apache.oltu.oauth2.*,
                             javax.ws.rs.ext,
                             javax.ws.rs,javax.ws.rs.core,
@@ -270,7 +268,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
                             org.ops4j.pax.web.service,
                             org.h2.*,
                         </Import-Package>
-                        <Bundle-Activator>org.opendaylight.aaa.AAAShiroActivator</Bundle-Activator>
                     </instructions>
                 </configuration>
             </plugin>
diff --git a/aaa-shiro/impl/src/main/java/org/opendaylight/aaa/AAAShiroActivator.java b/aaa-shiro/impl/src/main/java/org/opendaylight/aaa/AAAShiroActivator.java
deleted file mode 100644 (file)
index b1eb7e6..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2018 Inocybe Technologies 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;
-
-import java.util.Hashtable;
-import java.util.concurrent.CompletableFuture;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.blueprint.container.BlueprintEvent;
-import org.osgi.service.blueprint.container.BlueprintListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Bundle Activator.
- *
- * @author Thomas Pantelis
- */
-public class AAAShiroActivator implements BundleActivator, BlueprintListener {
-    private static final Logger LOG = LoggerFactory.getLogger(AAAShiroActivator.class);
-
-    private ServiceRegistration<?> eventHandlerReg;
-    private Bundle thisBundle;
-
-    @Override
-    public void start(BundleContext context) {
-        thisBundle = context.getBundle();
-        eventHandlerReg = context.registerService(BlueprintListener.class.getName(), this, new Hashtable<>());
-    }
-
-    @Override
-    public void stop(BundleContext context) {
-        possiblyFailAAAShiroProviderFuture(String.format("%s bundle stopped", thisBundle));
-
-        if (eventHandlerReg != null) {
-            try {
-                eventHandlerReg.unregister();
-            } catch (IllegalStateException e) {
-                // This can be safely ignored
-            }
-        }
-    }
-
-    @Override
-    public void blueprintEvent(BlueprintEvent event) {
-        if (!thisBundle.equals(event.getBundle())) {
-            return;
-        }
-
-        LOG.debug("Blueprint container event for bundle {}: {}", thisBundle, event.getType());
-
-        if (event.getType() == BlueprintEvent.DESTROYING) {
-            possiblyFailAAAShiroProviderFuture(String.format("Blueprint container for bundle %s is being destroyed",
-                    thisBundle));
-        }
-    }
-
-    private static void possiblyFailAAAShiroProviderFuture(String message) {
-        CompletableFuture<AAAShiroProvider> instanceFuture = AAAShiroProvider.getInstanceFuture();
-        if (!instanceFuture.isDone()) {
-            instanceFuture.completeExceptionally(new RuntimeException(message));
-        }
-    }
-}
index 709262dd9d8b247d7e0803ee8fc1fe0c34a0c9f5..36f38484ed5327ac6c15f36fce0e8da9b9f0e0e9 100644 (file)
@@ -23,11 +23,7 @@ import org.opendaylight.aaa.api.StoreBuilder;
 import org.opendaylight.aaa.api.TokenAuth;
 import org.opendaylight.aaa.api.TokenStore;
 import org.opendaylight.aaa.cert.api.ICertificateManager;
-import org.opendaylight.aaa.datastore.h2.H2Store;
 import org.opendaylight.aaa.datastore.h2.H2TokenStore;
-import org.opendaylight.aaa.datastore.h2.IdmLightConfig;
-import org.opendaylight.aaa.datastore.h2.IdmLightConfigBuilder;
-import org.opendaylight.aaa.datastore.h2.IdmLightSimpleConnectionProvider;
 import org.opendaylight.aaa.shiro.oauth2.OAuth2TokenServlet;
 import org.opendaylight.aaa.shiro.tokenauthrealm.ServiceLocator;
 import org.opendaylight.aaa.shiro.tokenauthrealm.auth.AuthenticationManager;
@@ -43,14 +39,13 @@ import org.slf4j.LoggerFactory;
 /**
  * Provider for AAA shiro implementation.
  */
-public class AAAShiroProvider {
+public final class AAAShiroProvider {
 
     private static final Logger LOG = LoggerFactory.getLogger(AAAShiroProvider.class);
 
-    private static final CompletableFuture<AAAShiroProvider> INSTANCE_FUTURE = new CompletableFuture();
-    private static volatile AAAShiroProvider INSTANCE;
-    private static IIDMStore iidmStore;
+    public static final CompletableFuture<AAAShiroProvider> INSTANCE_FUTURE = new CompletableFuture<>();
 
+    private final IIDMStore iidmStore;
     private final DataBroker dataBroker;
     private final ICertificateManager certificateManager;
     private final HttpService httpService;
@@ -60,19 +55,16 @@ public class AAAShiroProvider {
     private final TokenStore tokenStore;
 
     /**
-     * Provider for this bundle.
-     *
-     * @param dataBroker injected from blueprint
+     * Constructor.
      */
-    private AAAShiroProvider(final DataBroker dataBroker, final ICertificateManager certificateManager,
+    public AAAShiroProvider(final DataBroker dataBroker, final ICertificateManager certificateManager,
                              final CredentialAuth<PasswordCredentials> credentialAuth,
                              final ShiroConfiguration shiroConfiguration,
                              final HttpService httpService,
                              final String moonEndpointPath,
                              final String oauth2EndpointPath,
                              final DatastoreConfig datastoreConfig,
-                             final String dbUsername,
-                             final String dbPassword) {
+                             final IIDMStore idmStore) {
         this.dataBroker = dataBroker;
         this.certificateManager = certificateManager;
         this.shiroConfiguration = shiroConfiguration;
@@ -82,23 +74,23 @@ public class AAAShiroProvider {
 
         if (datastoreConfig != null && datastoreConfig.getStore()
                 .equals(DatastoreConfig.Store.H2DataStore)) {
-            final IdmLightConfig config = new IdmLightConfigBuilder()
-                    .dbUser(dbUsername).dbPwd(dbPassword).build();
-            iidmStore = new H2Store(new IdmLightSimpleConnectionProvider(config));
-            tokenStore = new H2TokenStore(datastoreConfig.getTimeToLive().longValue(),
+            this.iidmStore = idmStore;
+            this.tokenStore = new H2TokenStore(datastoreConfig.getTimeToLive().longValue(),
                     datastoreConfig.getTimeToWait().longValue());
         } else {
-            iidmStore = null;
-            tokenStore = null;
+            this.iidmStore = null;
+            this.tokenStore = null;
             LOG.info("AAA Datastore has not been initialized");
             return;
         }
-        this.initializeServices(credentialAuth, iidmStore, tokenStore);
+        this.initializeServices(credentialAuth, idmStore, tokenStore);
         try {
             this.registerServletContexts(this.httpService, this.moonEndpointPath, this.oauth2EndpointPath);
         } catch (final ServletException | NamespaceException e) {
             LOG.warn("Could not initialize AAA servlet endpoints", e);
         }
+
+        INSTANCE_FUTURE.complete(this);
     }
 
     private void registerServletContexts(final HttpService httpService, final String moonEndpointPath,
@@ -142,64 +134,16 @@ public class AAAShiroProvider {
         ServiceLocator.getInstance().setTokenStore(tokenStore);
     }
 
-    /**
-     * Singleton creation.
-     *
-     * @param dataBroker The DataBroker
-     * @param certificateManager the certificate manager
-     * @param credentialAuth The CredentialAuth
-     * @param shiroConfiguration shiro config
-     * @param httpService http service
-     * @param moonEndpointPath moon path
-     * @param oauth2EndpointPath oauth path
-     * @param datastoreConfig data store config
-     * @return the Provider
-     */
-    public static AAAShiroProvider newInstance(final DataBroker dataBroker,
-                                               final ICertificateManager certificateManager,
-                                               final CredentialAuth<PasswordCredentials> credentialAuth,
-                                               final ShiroConfiguration shiroConfiguration,
-                                               final HttpService httpService,
-                                               final String moonEndpointPath,
-                                               final String oauth2EndpointPath,
-                                               final DatastoreConfig datastoreConfig,
-                                               final String dbUsername,
-                                               final String dbPassword) {
-        INSTANCE = new AAAShiroProvider(dataBroker, certificateManager, credentialAuth, shiroConfiguration,
-                httpService, moonEndpointPath, oauth2EndpointPath, datastoreConfig, dbUsername, dbPassword);
-        INSTANCE_FUTURE.complete(INSTANCE);
-        return INSTANCE;
-    }
-
-    /**
-     * Singleton extraction.
-     *
-     * @return the Provider
-     */
-    public static AAAShiroProvider getInstance() {
-        return INSTANCE;
-    }
-
-    public static CompletableFuture<AAAShiroProvider> getInstanceFuture() {
-        return INSTANCE_FUTURE;
-    }
-
     /**
      * Get IDM data store.
      *
      * @return IIDMStore data store
-     */
-    public static IIDMStore getIdmStore() {
-        return iidmStore;
-    }
-
-    /**
-     * Set IDM data store, only used for test.
      *
-     * @param store data store
+     * @deprecated instead of calling this, just directly inject an IIDMStore into the class needing it
      */
-    public static void setIdmStore(IIDMStore store) {
-        iidmStore = store;
+    @Deprecated
+    public IIDMStore getIdmStore() {
+        return iidmStore;
     }
 
     /**
index f50f5abdcfb1249c3c3b87e9515b1757c8bc8363..78334bd763dfd6fcb51d7653c2d0a817dd9c1211 100644 (file)
@@ -31,8 +31,9 @@ public class H2Store implements IIDMStore {
     private final RoleStore roleStore;
     private final GrantStore grantStore;
 
-    public H2Store() {
-        this(new IdmLightSimpleConnectionProvider(new IdmLightConfigBuilder().build()));
+    public H2Store(String dbUsername, String dbPassword) {
+        this(new IdmLightSimpleConnectionProvider(
+                new IdmLightConfigBuilder().dbUser(dbUsername).dbPwd(dbPassword).build()));
     }
 
     public H2Store(ConnectionProvider connectionFactory) {
index 616da4435e0623b7bf6a695b251ad29c63dc5a6a..30b59fceec2e8d5c22e4ca921d4d04f33183aa3b 100644 (file)
@@ -25,7 +25,7 @@ import org.slf4j.LoggerFactory;
  *         Builder
  */
 @Immutable
-@Value.Style(stagedBuilder = true, strictBuilder = true, builder = "new",
+@Value.Style(strictBuilder = true, builder = "new",
     typeImmutable = "*Impl", visibility = ImplementationVisibility.PRIVATE)
 public abstract class IdmLightConfig {
 
@@ -67,20 +67,14 @@ public abstract class IdmLightConfig {
      *
      * @return data base user
      */
-    @Default
-    public String getDbUser() {
-        return "foo";
-    }
+    public abstract String getDbUser();
 
     /**
      * The database password. This is not the same as AAA credentials!
      *
      * @return data base password
      */
-    @Default
-    public String getDbPwd() {
-        return "bar";
-    }
+    public abstract String getDbPwd();
 
     /**
      * Timeout for database connections in seconds.
index 6b5fa953a0f071d04b293270d4a59dd170363862..aee7406183cec5f201cefcac8f7cc5dd73db0310 100644 (file)
@@ -5,7 +5,6 @@
  * 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.idm;
 
 import java.util.ArrayList;
@@ -21,6 +20,7 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
+import org.opendaylight.aaa.AAAShiroProvider;
 import org.opendaylight.aaa.api.IDMStoreException;
 import org.opendaylight.aaa.api.model.Claim;
 import org.opendaylight.aaa.api.model.Domain;
@@ -33,7 +33,6 @@ import org.opendaylight.aaa.api.model.Roles;
 import org.opendaylight.aaa.api.model.User;
 import org.opendaylight.aaa.api.model.UserPwd;
 import org.opendaylight.aaa.api.model.Users;
-import org.opendaylight.aaa.AAAShiroProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -52,6 +51,12 @@ public class DomainHandler {
 
     private static final Logger LOG = LoggerFactory.getLogger(DomainHandler.class);
 
+    private final AAAShiroProvider provider;
+
+    public DomainHandler(AAAShiroProvider provider) {
+        this.provider = provider;
+    }
+
     /**
      * Extracts all domains.
      *
@@ -63,7 +68,7 @@ public class DomainHandler {
         LOG.info("Get /domains");
         Domains domains = null;
         try {
-            domains = AAAShiroProvider.getInstance().getIdmStore().getDomains();
+            domains = provider.getIdmStore().getDomains();
         } catch (IDMStoreException e) {
             LOG.error("StoreException", e);
             IDMError idmerror = new IDMError();
@@ -88,7 +93,7 @@ public class DomainHandler {
         LOG.info("Get /domains/{}", domainId);
         Domain domain = null;
         try {
-            domain = AAAShiroProvider.getInstance().getIdmStore().readDomain(domainId);
+            domain = provider.getIdmStore().readDomain(domainId);
         } catch (IDMStoreException e) {
             LOG.error("StoreException", e);
             IDMError idmerror = new IDMError();
@@ -141,7 +146,7 @@ public class DomainHandler {
             if (domain.getDescription() == null) {
                 domain.setDescription("");
             }
-            domain = AAAShiroProvider.getInstance().getIdmStore().writeDomain(domain);
+            domain = provider.getIdmStore().writeDomain(domain);
         } catch (IDMStoreException e) {
             LOG.error("StoreException", e);
             IDMError idmerror = new IDMError();
@@ -171,7 +176,7 @@ public class DomainHandler {
         LOG.info("Put /domains/{}", domainId);
         try {
             domain.setDomainid(domainId);
-            domain = AAAShiroProvider.getInstance().getIdmStore().updateDomain(domain);
+            domain = provider.getIdmStore().updateDomain(domain);
             if (domain == null) {
                 IDMError idmerror = new IDMError();
                 idmerror.setMessage("Not found! Domain id:" + domainId);
@@ -203,7 +208,7 @@ public class DomainHandler {
         LOG.info("Delete /domains/{}", domainId);
 
         try {
-            Domain domain = AAAShiroProvider.getInstance().getIdmStore().deleteDomain(domainId);
+            Domain domain = provider.getIdmStore().deleteDomain(domainId);
             if (domain == null) {
                 IDMError idmerror = new IDMError();
                 idmerror.setMessage("Not found! Domain id:" + domainId);
@@ -260,7 +265,7 @@ public class DomainHandler {
 
         // validate domain id
         try {
-            domain = AAAShiroProvider.getInstance().getIdmStore().readDomain(domainId);
+            domain = provider.getIdmStore().readDomain(domainId);
         } catch (IDMStoreException e) {
             LOG.error("StoreException", e);
             IDMError idmerror = new IDMError();
@@ -276,7 +281,7 @@ public class DomainHandler {
         grant.setDomainid(domainId);
 
         try {
-            user = AAAShiroProvider.getInstance().getIdmStore().readUser(userId);
+            user = provider.getIdmStore().readUser(userId);
         } catch (IDMStoreException e) {
             LOG.error("StoreException", e);
             IDMError idmerror = new IDMError();
@@ -301,7 +306,7 @@ public class DomainHandler {
             return Response.status(404).entity(idmerror).build();
         }
         try {
-            role = AAAShiroProvider.getInstance().getIdmStore().readRole(roleId);
+            role = provider.getIdmStore().readRole(roleId);
         } catch (IDMStoreException e) {
             LOG.error("StoreException", e);
             IDMError idmerror = new IDMError();
@@ -317,7 +322,7 @@ public class DomainHandler {
 
         // see if grant already exists for this
         try {
-            Grant existingGrant = AAAShiroProvider.getInstance().getIdmStore().readGrant(domainId, userId, roleId);
+            Grant existingGrant = provider.getIdmStore().readGrant(domainId, userId, roleId);
             if (existingGrant != null) {
                 IDMError idmerror = new IDMError();
                 idmerror.setMessage("Grant already exists for did:" + domainId + " uid:" + userId + " rid:" + roleId);
@@ -333,7 +338,7 @@ public class DomainHandler {
 
         // create grant
         try {
-            grant = AAAShiroProvider.getInstance().getIdmStore().writeGrant(grant);
+            grant = provider.getIdmStore().writeGrant(grant);
         } catch (IDMStoreException e) {
             LOG.error("StoreException: ", e);
             IDMError idmerror = new IDMError();
@@ -368,7 +373,7 @@ public class DomainHandler {
         List<Role> roleList = new ArrayList<>();
 
         try {
-            domain = AAAShiroProvider.getInstance().getIdmStore().readDomain(domainId);
+            domain = provider.getIdmStore().readDomain(domainId);
         } catch (IDMStoreException se) {
             LOG.error("StoreException: ", se);
             IDMError idmerror = new IDMError();
@@ -398,7 +403,7 @@ public class DomainHandler {
 
         // find userid for user
         try {
-            Users users = AAAShiroProvider.getInstance().getIdmStore().getUsers(username, domainId);
+            Users users = provider.getIdmStore().getUsers(username, domainId);
             List<User> userList = users.getUsers();
             if (userList.size() == 0) {
                 IDMError idmerror = new IDMError();
@@ -417,11 +422,11 @@ public class DomainHandler {
             claim.setUsername(username);
             claim.setUserid(user.getUserid());
             try {
-                Grants grants = AAAShiroProvider.getInstance().getIdmStore().getGrants(domainId, user.getUserid());
+                Grants grants = provider.getIdmStore().getGrants(domainId, user.getUserid());
                 List<Grant> grantsList = grants.getGrants();
                 for (int i = 0; i < grantsList.size(); i++) {
                     Grant grant = grantsList.get(i);
-                    Role role = AAAShiroProvider.getInstance().getIdmStore().readRole(grant.getRoleid());
+                    Role role = provider.getIdmStore().readRole(grant.getRoleid());
                     roleList.add(role);
                 }
             } catch (IDMStoreException e) {
@@ -465,7 +470,7 @@ public class DomainHandler {
         List<Role> roleList = new ArrayList<>();
 
         try {
-            domain = AAAShiroProvider.getInstance().getIdmStore().readDomain(domainId);
+            domain = provider.getIdmStore().readDomain(domainId);
         } catch (IDMStoreException e) {
             LOG.error("StoreException", e);
             IDMError idmerror = new IDMError();
@@ -480,7 +485,7 @@ public class DomainHandler {
         }
 
         try {
-            user = AAAShiroProvider.getInstance().getIdmStore().readUser(userId);
+            user = provider.getIdmStore().readUser(userId);
         } catch (IDMStoreException e) {
             LOG.error("StoreException", e);
             IDMError idmerror = new IDMError();
@@ -495,11 +500,11 @@ public class DomainHandler {
         }
 
         try {
-            Grants grants = AAAShiroProvider.getInstance().getIdmStore().getGrants(domainId, userId);
+            Grants grants = provider.getIdmStore().getGrants(domainId, userId);
             List<Grant> grantsList = grants.getGrants();
             for (int i = 0; i < grantsList.size(); i++) {
                 Grant grant = grantsList.get(i);
-                Role role = AAAShiroProvider.getInstance().getIdmStore().readRole(grant.getRoleid());
+                Role role = provider.getIdmStore().readRole(grant.getRoleid());
                 roleList.add(role);
             }
         } catch (IDMStoreException e) {
@@ -536,7 +541,7 @@ public class DomainHandler {
         Role role;
 
         try {
-            domain = AAAShiroProvider.getInstance().getIdmStore().readDomain(domainId);
+            domain = provider.getIdmStore().readDomain(domainId);
         } catch (IDMStoreException e) {
             LOG.error("Error deleting Grant", e);
             IDMError idmerror = new IDMError();
@@ -551,7 +556,7 @@ public class DomainHandler {
         }
 
         try {
-            user = AAAShiroProvider.getInstance().getIdmStore().readUser(userId);
+            user = provider.getIdmStore().readUser(userId);
         } catch (IDMStoreException e) {
             LOG.error("StoreException", e);
             IDMError idmerror = new IDMError();
@@ -566,7 +571,7 @@ public class DomainHandler {
         }
 
         try {
-            role = AAAShiroProvider.getInstance().getIdmStore().readRole(roleId);
+            role = provider.getIdmStore().readRole(roleId);
         } catch (IDMStoreException e) {
             LOG.error("StoreException", e);
             IDMError idmerror = new IDMError();
@@ -582,13 +587,13 @@ public class DomainHandler {
 
         // see if grant already exists
         try {
-            Grant existingGrant = AAAShiroProvider.getInstance().getIdmStore().readGrant(domainId, userId, roleId);
+            Grant existingGrant = provider.getIdmStore().readGrant(domainId, userId, roleId);
             if (existingGrant == null) {
                 IDMError idmerror = new IDMError();
                 idmerror.setMessage("Grant does not exist for did:" + domainId + " uid:" + userId + " rid:" + roleId);
                 return Response.status(404).entity(idmerror).build();
             }
-            existingGrant = AAAShiroProvider.getInstance().getIdmStore().deleteGrant(existingGrant.getGrantid());
+            existingGrant = provider.getIdmStore().deleteGrant(existingGrant.getGrantid());
         } catch (IDMStoreException e) {
             LOG.error("StoreException", e);
             IDMError idmerror = new IDMError();
index 77a034575a151b32cf87eb7566faf4827b0506b3..ae1ba6e4d5727fb42a2db4c0b42736421c11d432 100644 (file)
@@ -8,13 +8,11 @@
 
 package org.opendaylight.aaa.shiro.idm;
 
-import java.util.Arrays;
-import java.util.HashSet;
+import com.google.common.collect.ImmutableSet;
 import java.util.Set;
 import javax.ws.rs.core.Application;
+import org.opendaylight.aaa.AAAShiroProvider;
 import org.opendaylight.aaa.provider.GsonProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * A JAX-RS application for IdmLight. The REST endpoints delivered by this
@@ -29,14 +27,13 @@ import org.slf4j.LoggerFactory;
  * store.
  *
  * @author liemmn
- * @see <code>org.opendaylight.aaa.shiro.idm.rest.DomainHandler</code>
- * @see <code>org.opendaylight.aaa.shiro.idm.rest.UserHandler</code>
- * @see <code>org.opendaylight.aaa.shiro.idm.rest.RoleHandler</code>
+ *
+ * @see org.opendaylight.aaa.shiro.idm.DomainHandler
+ * @see org.opendaylight.aaa.shiro.idm.UserHandler
+ * @see org.opendaylight.aaa.shiro.idm.RoleHandler
  */
 public class IdmLightApplication extends Application {
 
-    private static final Logger LOG = LoggerFactory.getLogger(IdmLightApplication.class);
-
     // TODO create a bug to address the fact that the implementation assumes 128
     // as the max length, even though this claims 256.
     /**
@@ -44,12 +41,19 @@ public class IdmLightApplication extends Application {
      */
     public static final int MAX_FIELD_LEN = 256;
 
-    public IdmLightApplication() {
+    private final AAAShiroProvider provider;
+
+    public IdmLightApplication(AAAShiroProvider provider) {
+        this.provider = provider;
     }
 
     @Override
-    public Set<Class<?>> getClasses() {
-        return new HashSet<>(Arrays.asList(GsonProvider.class,
-                DomainHandler.class, RoleHandler.class, UserHandler.class));
+    public Set<Object> getSingletons() {
+        return ImmutableSet.builderWithExpectedSize(32)
+                    .add(new GsonProvider<>())
+                    .add(new DomainHandler(provider))
+                    .add(new RoleHandler(provider))
+                    .add(new UserHandler(provider))
+                    .build();
     }
 }
index bf33faca6b8c23329a81de33be89bf6f9ee8da36..bf6aae8120310b29af9e96273e56b32247cd2f62 100644 (file)
@@ -5,7 +5,6 @@
  * 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.idm;
 
 import com.google.common.base.Preconditions;
@@ -15,7 +14,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
-import org.opendaylight.aaa.AAAShiroProvider;
 import org.opendaylight.aaa.api.AuthenticationException;
 import org.opendaylight.aaa.api.Claim;
 import org.opendaylight.aaa.api.CredentialAuth;
@@ -55,6 +53,12 @@ public class IdmLightProxy implements CredentialAuth<PasswordCredentials>, IdMSe
                 new ConcurrentHashMap<PasswordCredentials, Claim>());
     }
 
+    private final IIDMStore idmStore;
+
+    public IdmLightProxy(IIDMStore idmStore) {
+        this.idmStore = idmStore;
+    }
+
     @Override
     public Claim authenticate(PasswordCredentials creds) {
         Preconditions.checkNotNull(creds);
@@ -92,7 +96,7 @@ public class IdmLightProxy implements CredentialAuth<PasswordCredentials>, IdMSe
         }
     }
 
-    private static Claim dbAuthenticate(PasswordCredentials creds) {
+    private Claim dbAuthenticate(PasswordCredentials creds) {
         Domain domain = null;
         User user = null;
         String credsDomain = creds.domain() == null ? IIDMStore.DEFAULT_DOMAIN : creds.domain();
@@ -100,7 +104,7 @@ public class IdmLightProxy implements CredentialAuth<PasswordCredentials>, IdMSe
         // TODO: ensure domain names are unique change to 'getDomain'
         LOG.debug("get domain");
         try {
-            domain = AAAShiroProvider.getInstance().getIdmStore().readDomain(credsDomain);
+            domain = idmStore.readDomain(credsDomain);
             if (domain == null) {
                 throw new AuthenticationException("Domain :" + credsDomain + " does not exist");
             }
@@ -111,7 +115,7 @@ public class IdmLightProxy implements CredentialAuth<PasswordCredentials>, IdMSe
         // check to see user exists and passes cred check
         try {
             LOG.debug("check user / pwd");
-            Users users = AAAShiroProvider.getInstance().getIdmStore().getUsers(creds.username(), credsDomain);
+            Users users = idmStore.getUsers(creds.username(), credsDomain);
             List<User> userList = users.getUsers();
             if (userList.size() == 0) {
                 throw new AuthenticationException("User :" + creds.username()
@@ -129,12 +133,11 @@ public class IdmLightProxy implements CredentialAuth<PasswordCredentials>, IdMSe
             // get all grants & roles for this domain and user
             LOG.debug("get grants");
             List<String> roles = new ArrayList<>();
-            Grants grants = AAAShiroProvider.getInstance().getIdmStore().getGrants(domain.getDomainid(),
-                    user.getUserid());
+            Grants grants = idmStore.getGrants(domain.getDomainid(), user.getUserid());
             List<Grant> grantList = grants.getGrants();
             for (int z = 0; z < grantList.size(); z++) {
                 Grant grant = grantList.get(z);
-                Role role = AAAShiroProvider.getInstance().getIdmStore().readRole(grant.getRoleid());
+                Role role = idmStore.readRole(grant.getRoleid());
                 if (role != null) {
                     roles.add(role.getName());
                 }
@@ -157,16 +160,16 @@ public class IdmLightProxy implements CredentialAuth<PasswordCredentials>, IdMSe
 
     @Override
     public List<String> listDomains(String userId) {
-        return new IdMServiceImpl(AAAShiroProvider.getInstance().getIdmStore()).listDomains(userId);
+        return new IdMServiceImpl(idmStore).listDomains(userId);
     }
 
     @Override
     public List<String> listRoles(String userId, String domainName) {
-        return new IdMServiceImpl(AAAShiroProvider.getInstance().getIdmStore()).listRoles(userId, domainName);
+        return new IdMServiceImpl(idmStore).listRoles(userId, domainName);
     }
 
     @Override
     public List<String> listUserIDs() throws IDMStoreException {
-        return new IdMServiceImpl(AAAShiroProvider.getInstance().getIdmStore()).listUserIDs();
+        return new IdMServiceImpl(idmStore).listUserIDs();
     }
 }
index e91f810d4c3869d7f3519173d55ab309e0448d21..921c94c33432923ce069671797ea1cde90a538b4 100644 (file)
@@ -5,7 +5,6 @@
  * 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.idm;
 
 import javax.ws.rs.Consumes;
@@ -40,8 +39,15 @@ import org.slf4j.LoggerFactory;
  */
 @Path("/v1/roles")
 public class RoleHandler {
+
     private static final Logger LOG = LoggerFactory.getLogger(RoleHandler.class);
 
+    private final AAAShiroProvider provider;
+
+    public RoleHandler(AAAShiroProvider provider) {
+        this.provider = provider;
+    }
+
     /**
      * Extracts all roles.
      *
@@ -54,7 +60,7 @@ public class RoleHandler {
         LOG.info("get /roles");
         Roles roles = null;
         try {
-            roles = AAAShiroProvider.getInstance().getIdmStore().getRoles();
+            roles = provider.getIdmStore().getRoles();
         } catch (IDMStoreException e) {
             LOG.error("Internal error getting the roles", e);
             return new IDMError(500, "internal error getting roles", e.getMessage()).response();
@@ -78,7 +84,7 @@ public class RoleHandler {
         Role role = null;
 
         try {
-            role = AAAShiroProvider.getInstance().getIdmStore().readRole(id);
+            role = provider.getIdmStore().readRole(id);
         } catch (IDMStoreException e) {
             LOG.error("Internal error getting the role", e);
             return new IDMError(500, "internal error getting roles", e.getMessage()).response();
@@ -143,7 +149,7 @@ public class RoleHandler {
                         .response();
             }
 
-            role = AAAShiroProvider.getInstance().getIdmStore().writeRole(role);
+            role = provider.getIdmStore().writeRole(role);
         } catch (IDMStoreException e) {
             LOG.error("Internal error creating role", e);
             return new IDMError(500, "internal error creating role", e.getMessage()).response();
@@ -175,19 +181,19 @@ public class RoleHandler {
 
             // name
             // TODO: names should be unique
-            if ((role.getName() != null) && (role.getName().length() > IdmLightApplication.MAX_FIELD_LEN)) {
+            if (role.getName() != null && role.getName().length() > IdmLightApplication.MAX_FIELD_LEN) {
                 return new IDMError(400, "role name max length is :" + IdmLightApplication.MAX_FIELD_LEN, "")
                         .response();
             }
 
             // description
-            if ((role.getDescription() != null)
-                    && (role.getDescription().length() > IdmLightApplication.MAX_FIELD_LEN)) {
+            if (role.getDescription() != null
+                    && role.getDescription().length() > IdmLightApplication.MAX_FIELD_LEN) {
                 return new IDMError(400, "role description max length is :" + IdmLightApplication.MAX_FIELD_LEN, "")
                         .response();
             }
 
-            role = AAAShiroProvider.getInstance().getIdmStore().updateRole(role);
+            role = provider.getIdmStore().updateRole(role);
             if (role == null) {
                 return new IDMError(404, "role id not found :" + id, "").response();
             }
@@ -215,7 +221,7 @@ public class RoleHandler {
         LOG.info("Delete /roles/{}", id);
 
         try {
-            Role role = AAAShiroProvider.getInstance().getIdmStore().deleteRole(id);
+            Role role = provider.getIdmStore().deleteRole(id);
             if (role == null) {
                 return new IDMError(404, "role id not found :" + id, "").response();
             }
index 2a031cd74833ead37b0a8335f8d67d074f356764..546bec1862de7f3c4cd13da9a2c07dc46416e5cb 100644 (file)
@@ -5,11 +5,9 @@
  * 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.idm;
 
 import java.util.Collection;
-
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
@@ -21,11 +19,11 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
+import org.opendaylight.aaa.AAAShiroProvider;
 import org.opendaylight.aaa.api.IDMStoreException;
 import org.opendaylight.aaa.api.model.IDMError;
 import org.opendaylight.aaa.api.model.User;
 import org.opendaylight.aaa.api.model.Users;
-import org.opendaylight.aaa.AAAShiroProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -76,6 +74,12 @@ public class UserHandler {
      */
     private static final String DEFAULT_EMAIL = "";
 
+    private final AAAShiroProvider provider;
+
+    public UserHandler(AAAShiroProvider provider) {
+        this.provider = provider;
+    }
+
     /**
      * Extracts all users. The password and salt fields are redacted for
      * security reasons.
@@ -88,7 +92,7 @@ public class UserHandler {
         LOG.info("GET /auth/v1/users  (extracts all users)");
 
         try {
-            final Users users = AAAShiroProvider.getInstance().getIdmStore().getUsers();
+            final Users users = provider.getIdmStore().getUsers();
 
             // Redact the password and salt for security purposes.
             final Collection<User> usersList = users.getUsers();
@@ -118,7 +122,7 @@ public class UserHandler {
         LOG.info("GET auth/v1/users/ {}  (extract user with specified id)", id);
 
         try {
-            final User user = AAAShiroProvider.getInstance().getIdmStore().readUser(id);
+            final User user = provider.getIdmStore().readUser(id);
 
             if (user == null) {
                 final String error = "user not found! id: " + id;
@@ -225,7 +229,7 @@ public class UserHandler {
         try {
             // At this point, fields have been properly verified. Create the
             // user account
-            final User createdUser = AAAShiroProvider.getInstance().getIdmStore().writeUser(user);
+            final User createdUser = provider.getIdmStore().writeUser(user);
             user.setUserid(createdUser.getUserid());
         } catch (IDMStoreException se) {
             return internalError("creating", se);
@@ -280,7 +284,7 @@ public class UserHandler {
                 return providedFieldTooLong("domain", IdmLightApplication.MAX_FIELD_LEN);
             }
 
-            user = AAAShiroProvider.getInstance().getIdmStore().updateUser(user);
+            user = provider.getIdmStore().updateUser(user);
             if (user == null) {
                 return new IDMError(404, String.format("User not found for id %s", id), "").response();
             }
@@ -310,7 +314,7 @@ public class UserHandler {
         LOG.info("DELETE /auth/v1/users/{}  (Delete a user account)", id);
 
         try {
-            final User user = AAAShiroProvider.getInstance().getIdmStore().deleteUser(id);
+            final User user = provider.getIdmStore().deleteUser(id);
 
             if (user == null) {
                 return new IDMError(404, String.format("Error deleting user.  " + "Couldn't find user with id %s", id),
index af53638a1c603d03792722b8ca4f2b94a0d4aa5a..a21e67ebe164130eae738fa0881f0c4f045265fc 100644 (file)
@@ -5,11 +5,8 @@
  * 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.opendaylight.aaa.shiro.principal.ODLPrincipalImpl.createODLPrincipal;
-
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
@@ -41,13 +38,13 @@ import org.apache.shiro.subject.PrincipalCollection;
 import org.opendaylight.aaa.api.shiro.principal.ODLPrincipal;
 import org.opendaylight.aaa.cert.api.ICertificateManager;
 import org.opendaylight.aaa.provider.GsonProvider;
-import org.opendaylight.aaa.AAAShiroProvider;
 import org.opendaylight.aaa.shiro.keystone.domain.KeystoneAuth;
 import org.opendaylight.aaa.shiro.keystone.domain.KeystoneToken;
+import org.opendaylight.aaa.shiro.principal.ODLPrincipalImpl;
 import org.opendaylight.aaa.shiro.realm.util.http.SimpleHttpClient;
 import org.opendaylight.aaa.shiro.realm.util.http.SimpleHttpRequest;
 import org.opendaylight.aaa.shiro.realm.util.http.UntrustedSSL;
-import org.opendaylight.aaa.shiro.principal.ODLPrincipalImpl;
+import org.opendaylight.aaa.shiro.web.env.ThreadLocals;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -76,6 +73,13 @@ public class KeystoneAuthRealm extends AuthorizingRealm {
 
     private final LoadingCache<Boolean, SimpleHttpClient> clientCache = buildCache();
 
+    private final ICertificateManager certManager;
+
+    public KeystoneAuthRealm() {
+        this.certManager = Objects.requireNonNull(ThreadLocals.CERT_MANAGER_TL.get());
+        LOG.info("KeystoneAuthRealm created");
+    }
+
     @Override
     protected AuthorizationInfo doGetAuthorizationInfo(final PrincipalCollection principalCollection) {
         final Object primaryPrincipal = getAvailablePrincipal(principalCollection);
@@ -181,10 +185,7 @@ public class KeystoneAuthRealm extends AuthorizingRealm {
                 .build(new CacheLoader<Boolean, SimpleHttpClient>() {
                     @Override
                     public SimpleHttpClient load(Boolean withSslVerification) throws Exception {
-                        return buildClient(
-                                withSslVerification,
-                                AAAShiroProvider.getInstance().getCertificateManager(),
-                                SimpleHttpClient.clientBuilder());
+                        return buildClient(withSslVerification, certManager, SimpleHttpClient.clientBuilder());
                     }
                 });
     }
index 575184cffba2fd9c0c2d88b9e6b1dc6356b084b9..ff3c01d9deb71918382e4cc00b5bf61663c871c2 100644 (file)
@@ -5,19 +5,19 @@
  * 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 com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.ExecutionException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import org.apache.shiro.subject.Subject;
 import org.apache.shiro.web.filter.authz.AuthorizationFilter;
-import org.opendaylight.aaa.AAAShiroProvider;
+import org.opendaylight.aaa.shiro.web.env.ThreadLocals;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -35,8 +35,9 @@ import org.slf4j.LoggerFactory;
  * This model exposes the ability to manipulate policy information for specific paths
  * based on a tuple of (role, http_permission_list).
  *
- * This mechanism will only work when put behind <code>authcBasic</code>
+ * <p>This mechanism will only work when put behind <code>authcBasic</code>.
  */
+@SuppressWarnings("checkstyle:AbbreviationAsWordInName")
 public class MDSALDynamicAuthorizationFilter extends AuthorizationFilter {
 
     private static final Logger LOG = LoggerFactory.getLogger(MDSALDynamicAuthorizationFilter.class);
@@ -54,26 +55,15 @@ public class MDSALDynamicAuthorizationFilter extends AuthorizationFilter {
         }
     }
 
-    @Override
-    public boolean isAccessAllowed(final ServletRequest request, final ServletResponse response,
-                                   final Object mappedValue) {
-        final DataBroker dataBroker = AAAShiroProvider.getInstance().getDataBroker();
-        return isAccessAllowed(request, response, mappedValue, dataBroker);
+    private final DataBroker dataBroker;
+
+    public MDSALDynamicAuthorizationFilter() {
+        this.dataBroker = Objects.requireNonNull(ThreadLocals.DATABROKER_TL.get());
     }
 
+    @Override
     public boolean isAccessAllowed(final ServletRequest request, final ServletResponse response,
-                                   final Object mappedValue, final DataBroker dataBroker) {
-
-        // FIXME:  Remove this check when Bug 7793 is resolved.
-        // Bug 7793: shiro.ini needs to die
-        // shiro instantiates this Filter as part of the web container initialization, but has
-        // no way of passing the DataBroker reference.  Thus, the dependency cannot be expressed
-        // easily.  Hitherto, the Filter may be instantiated prior to the DataBroker actually being
-        // made available.  For now, just fail out (deny access) until the DataBroker becomes
-        // available (injected via Blueprint in AAAShiroProvider.newInstance(DataBroker))
-        if (dataBroker == null) {
-            return false;
-        }
+                                   final Object mappedValue) {
         final Subject subject = getSubject(request, response);
         final HttpServletRequest httpServletRequest = (HttpServletRequest)request;
         final String requestURI = httpServletRequest.getRequestURI();
index 508984e37b1e7967d1cc5e82f47d324b236e7446..dac069171b03a491b37f334180d1a8d4bacdae7a 100644 (file)
@@ -12,19 +12,23 @@ import com.google.common.base.Optional;
 import com.google.common.collect.Sets;
 import com.google.common.util.concurrent.CheckedFuture;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
-import org.apache.shiro.authc.*;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.SimpleAuthenticationInfo;
 import org.apache.shiro.authz.AuthorizationInfo;
 import org.apache.shiro.authz.SimpleAuthorizationInfo;
 import org.apache.shiro.realm.AuthorizingRealm;
 import org.apache.shiro.subject.PrincipalCollection;
-import org.opendaylight.aaa.AAAShiroProvider;
 import org.opendaylight.aaa.api.SHA256Calculator;
 import org.opendaylight.aaa.api.shiro.principal.ODLPrincipal;
 import org.opendaylight.aaa.shiro.principal.ODLPrincipalImpl;
 import org.opendaylight.aaa.shiro.realm.util.TokenUtils;
 import org.opendaylight.aaa.shiro.realm.util.http.header.HeaderUtils;
+import org.opendaylight.aaa.shiro.web.env.ThreadLocals;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -51,8 +55,11 @@ public class MdsalRealm extends AuthorizingRealm {
     private static final InstanceIdentifier<Authentication> AUTH_IID =
             InstanceIdentifier.builder(Authentication.class).build();
 
+    private final DataBroker dataBroker;
+
     public MdsalRealm() {
-        LOG.info("Instantiating {}", MdsalRealm.class.getName());
+        this.dataBroker = Objects.requireNonNull(ThreadLocals.DATABROKER_TL.get());
+        LOG.info("MdsalRealm created");
     }
 
     @Override
@@ -91,7 +98,6 @@ public class MdsalRealm extends AuthorizingRealm {
      * @return the <code>authentication</code> container
      */
     private Optional<Authentication> getAuthenticationContainer() {
-        final DataBroker dataBroker = AAAShiroProvider.getInstance().getDataBroker();
         try (final ReadOnlyTransaction ro = dataBroker.newReadOnlyTransaction()) {
             final CheckedFuture<Optional<Authentication>, ReadFailedException> result =
                     ro.read(LogicalDatastoreType.CONFIGURATION, AUTH_IID);
index 9e290021cc751bb5d2fe33af495155d62a949b5f..5227c6d2180ebea05eebcd753a1f2b312d382328 100644 (file)
@@ -35,6 +35,6 @@ public class ODLActiveDirectoryRealm extends ActiveDirectoryRealm {
     private static final Logger LOG = LoggerFactory.getLogger(ODLActiveDirectoryRealm.class);
 
     public ODLActiveDirectoryRealm() {
-        LOG.debug("Creating an instance of ODLActiveDirectoryRealm to use with AAA");
+        LOG.info("ODLActiveDirectoryRealm created");
     }
 }
index 63d7bd171152ed1e4a1a951a2099a88a4c65de16..878cc51f43fe97e29fece56570f7cb9bee1aaf5a 100644 (file)
@@ -43,7 +43,7 @@ public class ODLJndiLdapRealmAuthNOnly extends JndiLdapRealm {
      * Adds debugging information surrounding creation of ODLJndiLdapRealm
      */
     public ODLJndiLdapRealmAuthNOnly() {
-        LOG.debug("Creating ODLJndiLdapRealmAuthNOnly");
+        LOG.info("ODLJndiLdapRealmAuthNOnly realm created");
     }
 
     /*
index dc33717fe206b0ea7eb85687549e74c03d6e6f0c..c79630dd8e0183106d1faf33752ced9b5a08005f 100644 (file)
@@ -5,7 +5,6 @@
  * 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 java.util.List;
@@ -39,9 +38,7 @@ public class KarafIniWebEnvironment extends IniWebEnvironment {
                 KarafIniWebEnvironment.class.getName());
     }
 
-    private static Ini createIniFromClusteredAppConfig(
-            final ShiroConfiguration shiroConfiguration) {
-
+    private static Ini createIniFromClusteredAppConfig(final ShiroConfiguration shiroConfiguration) {
         final Ini ini = new Ini();
 
         final Ini.Section mainSection = ini.addSection(MAIN_SECTION_HEADER);
@@ -66,7 +63,10 @@ public class KarafIniWebEnvironment extends IniWebEnvironment {
     @Override
     public void init() {
         try {
-            AAAShiroProvider provider = AAAShiroProvider.getInstanceFuture().get();
+            AAAShiroProvider provider = AAAShiroProvider.INSTANCE_FUTURE.get();
+
+            ThreadLocals.DATABROKER_TL.set(provider.getDataBroker());
+            ThreadLocals.CERT_MANAGER_TL.set(provider.getCertificateManager());
 
             // Initialize the Shiro environment from clustered-app-config
             final Ini ini = createIniFromClusteredAppConfig(provider.getShiroConfiguration());
@@ -74,6 +74,9 @@ public class KarafIniWebEnvironment extends IniWebEnvironment {
             super.init();
         } catch (InterruptedException | ExecutionException e) {
             throw new RuntimeException("Error obtaining AAAShiroProvider", e);
+        } finally {
+            ThreadLocals.DATABROKER_TL.remove();
+            ThreadLocals.CERT_MANAGER_TL.remove();
         }
     }
 }
index 04b33d749eecc2bb524b781e15da7a62068da3ef..1bc7e4d7b8e450a47d4749987dd27b4d57f2c39f 100644 (file)
@@ -23,5 +23,4 @@ public class KarafIniWebEnvironmentLoaderListener extends EnvironmentLoaderListe
     protected Class<?> determineWebEnvironmentClass(ServletContext servletContext) {
         return KarafIniWebEnvironment.class;
     }
-
 }
diff --git a/aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/web/env/ThreadLocals.java b/aaa-shiro/impl/src/main/java/org/opendaylight/aaa/shiro/web/env/ThreadLocals.java
new file mode 100644 (file)
index 0000000..ade5422
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2018 Inocybe Technologies 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 org.opendaylight.aaa.cert.api.ICertificateManager;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+
+/**
+ * Holds ThreadLocal variables used to indirectly inject instances into classes that are instantiated by the Shiro
+ * lib. Not ideal but a necessary evil to avoid static instances.
+ *
+ * @author Thomas Pantelis
+ */
+public interface ThreadLocals {
+    ThreadLocal<DataBroker> DATABROKER_TL = new ThreadLocal<>();
+
+    ThreadLocal<ICertificateManager> CERT_MANAGER_TL = new ThreadLocal<>();
+}
index 1b948c19a94eacbca3cdf48daa69fd42ce49a246..55389e23663a57275e94293f6951432ed5b2b755 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.aaa.shiro.web.env;
 
 import javax.servlet.ServletException;
 import org.eclipse.jetty.servlets.CrossOriginFilter;
+import org.opendaylight.aaa.AAAShiroProvider;
 import org.opendaylight.aaa.filterchain.filters.CustomFilterAdapter;
 import org.opendaylight.aaa.shiro.filters.AAAShiroFilter;
 import org.opendaylight.aaa.shiro.idm.IdmLightApplication;
@@ -30,14 +31,11 @@ public class WebInitializer {
 
     private final WebContextRegistration registraton;
 
-    public WebInitializer(WebServer webServer) throws ServletException {
+    public WebInitializer(WebServer webServer, AAAShiroProvider provider) throws ServletException {
         this.registraton = webServer.registerWebContext(WebContext.builder().contextPath("auth").supportsSessions(true)
 
-            .addServlet(ServletDetails.builder().servlet(new com.sun.jersey.spi.container.servlet.ServletContainer())
-                 // TODO test using javax.ws.rs.core.Application.class.getName() instead; NB .core.
-                 //   or, even much more better, use new ServletContainer(new IdmLightApplication()) ...
-                 //   as that is, ultimately, one of the main reasons for doing it like this!
-                .putInitParam("javax.ws.rs.Application", IdmLightApplication.class.getName())
+            .addServlet(ServletDetails.builder().servlet(new com.sun.jersey.spi.container.servlet.ServletContainer(
+                    new IdmLightApplication(provider)))
                 .putInitParam("com.sun.jersey.api.json.POJOMappingFeature", "true")
                 .putInitParam("jersey.config.server.provider.packages", "org.opendaylight.aaa.impl.provider")
                 .addUrlPattern("/*").build())
index 1ba0d22c398385c6d932aec05d16cdd12d9ef001..efe0cb22b8d4553dd37d2d51972fd482f2429303 100644 (file)
@@ -61,7 +61,7 @@
     <!-- Start ldapRealm commented out
     <main>
         <pair-key>ldapRealm</pair-key>
-        <pair-value>ODLJndiLdapRealmAuthNOnly</pair-value>
+        <pair-value>org.opendaylight.aaa.shiro.realm.ODLJndiLdapRealmAuthNOnly</pair-value>
     </main>
     <main>
         <pair-key>ldapRealm.userDnTemplate</pair-key>
@@ -97,7 +97,7 @@
     <!-- Start adRealm commented out
     <main>
         <pair-key>adRealm</pair-key>
-        <pair-value>ODLActiveDirectoryRealm</pair-value>
+        <pair-value>org.opendaylight.aaa.shiro.realm.ODLActiveDirectoryRealm</pair-value>
     </main>
     <main>
         <pair-key>adRealm.searchBase</pair-key>
     <!-- Start mdsalRealm commented out
     <main>
         <pair-key>mdsalRealm</pair-key>
-        <pair-value>MdsalRealm</pair-value>
+        <pair-value>org.opendaylight.aaa.shiro.realm.MdsalRealm</pair-value>
     </main>
     End mdsalRealm commented out-->
 
     <!-- Start moonAuthRealm commented out
     <main>
         <pair-key>moonAuthRealm</pair-key>
-        <pair-value>MoonRealm</pair-value>
+        <pair-value>org.opendaylight.aaa.shiro.realm.MoonRealm</pair-value>
     </main>
     <main>
         <pair-key>moonAuthRealm.moonServerURL</pair-key>
     <!-- Start keystoneAuthRealm commented out
     <main>
         <pair-key>keystoneAuthRealm</pair-key>
-        <pair-value>KeystoneAuthRealm</pair-value>
+        <pair-value>org.opendaylight.aaa.shiro.realm.KeystoneAuthRealm</pair-value>
     </main>
     <main>
         <pair-key>keystoneAuthRealm.url</pair-key>
index 16514652a65611bc3f05a9ff864c0b73709fd767..2c0ca0c12a51e940432d3bb0eadf5d888de2fb45 100644 (file)
@@ -20,9 +20,16 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
         default-config-file-name="aaa-datastore-config.xml"
         binding-class="org.opendaylight.yang.gen.v1.urn.opendaylight.aaa.app.config.rev170619.DatastoreConfig" />
 
+  <bean id="idmStore" class="org.opendaylight.aaa.datastore.h2.H2Store">
+    <argument value="${dbUsername}" />
+    <argument value="${dbPassword}" />
+  </bean>
+
   <bean id="IdmLightProxy" class="org.opendaylight.aaa.shiro.idm.IdmLightProxy">
+    <argument ref="idmStore" />
   </bean>
 
+  <service ref="idmStore" interface="org.opendaylight.aaa.api.IIDMStore" odl:type="default"/>
   <service ref="IdmLightProxy" interface="org.opendaylight.aaa.api.IdMService" odl:type="default"/>
   <service ref="IdmLightProxy" interface="org.opendaylight.aaa.api.CredentialAuth" odl:type="default"/>
 
@@ -46,7 +53,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   </cm:property-placeholder>
 
   <bean id="provider"
-        class="org.opendaylight.aaa.AAAShiroProvider" factory-method="newInstance"
+        class="org.opendaylight.aaa.AAAShiroProvider"
         init-method="init" destroy-method="close">
     <argument ref="dataBroker" />
     <argument ref="certManager" />
@@ -56,8 +63,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <argument value="/moon" />
     <argument value="/oauth2" />
     <argument ref="datastoreConfig" />
-    <argument value="${dbUsername}" />
-    <argument value="${dbPassword}" />
+    <argument ref="idmStore" />
   </bean>
 
   <bean id="aaa" class="org.opendaylight.aaa.shiro.filters.AAAFilter" />
@@ -69,5 +75,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <reference id="webServer" interface="org.opendaylight.aaa.web.WebServer" />
   <bean id="webInitializer" class="org.opendaylight.aaa.shiro.web.env.WebInitializer" destroy-method="close">
     <argument ref="webServer"/>
+    <argument ref="provider"/>
   </bean>
 </blueprint>
index 6f3d6f49e2a311a344fb354e684153c0071e0871..d3f5aa5a80b0a8ddd2e5470caface198acbf7e2f 100644 (file)
@@ -61,7 +61,6 @@ public class DomainStoreTest {
 
     @Test
     public void deleteDomainsTest() throws SQLException, Exception {
-        DomainStore ds = new DomainStore(new IdmLightSimpleConnectionProvider(new IdmLightConfigBuilder().build()));
         String domainId = "Testing12345";
 
         // Run Test
@@ -69,6 +68,10 @@ public class DomainStoreTest {
         testDomain.setDomainid(domainId);
         testDomain.setName(domainId);
         testDomain.setEnabled(Boolean.TRUE);
+
+        DomainStore ds = new DomainStore(
+                new IdmLightSimpleConnectionProvider(new IdmLightConfigBuilder().dbUser("foo").dbPwd("bar").build()));
+
         ds.createDomain(testDomain);
         assertEquals(ds.getDomain(domainId).getDomainid(), domainId);
         ds.deleteDomain(domainId);
index 4f6722455c3a73d82d300085320f89004d38e92c..52d3c73a5d0be1e5c5e8bee956a111c7ce241114 100644 (file)
@@ -53,23 +53,26 @@ public class H2StoreTest {
 
     @Before
     public void before() throws StoreException, SQLException {
-        UserStore us = new UserStore(new IdmLightSimpleConnectionProvider(new IdmLightConfigBuilder().build()));
+        IdmLightSimpleConnectionProvider dbConnectionFactory = new IdmLightSimpleConnectionProvider(
+                new IdmLightConfigBuilder().dbUser("foo").dbPwd("bar").build());
+        UserStore us = new UserStore(dbConnectionFactory);
         us.dbClean();
-        DomainStore ds = new DomainStore(new IdmLightSimpleConnectionProvider(new IdmLightConfigBuilder().build()));
+        DomainStore ds = new DomainStore(dbConnectionFactory);
         ds.dbClean();
-        RoleStore rs = new RoleStore(new IdmLightSimpleConnectionProvider(new IdmLightConfigBuilder().build()));
+        RoleStore rs = new RoleStore(dbConnectionFactory);
         rs.dbClean();
-        GrantStore gs = new GrantStore(new IdmLightSimpleConnectionProvider(new IdmLightConfigBuilder().build()));
+        GrantStore gs = new GrantStore(dbConnectionFactory);
         gs.dbClean();
 
-        h2Store = new H2Store();
+        h2Store = new H2Store("foo", "bar");
     }
 
     @Test
     public void testCreateDefaultDomain() throws StoreException {
         Domain domain = new Domain();
         Assert.assertEquals(true, domain != null);
-        DomainStore ds = new DomainStore(new IdmLightSimpleConnectionProvider(new IdmLightConfigBuilder().build()));
+        DomainStore ds = new DomainStore(
+                new IdmLightSimpleConnectionProvider(new IdmLightConfigBuilder().dbUser("foo").dbPwd("bar").build()));
         domain.setName(IIDMStore.DEFAULT_DOMAIN);
         domain.setEnabled(true);
         domain = ds.createDomain(domain);
@@ -99,7 +102,8 @@ public class H2StoreTest {
 
     @Test
     public void testUpdatingUserEmail() throws StoreException {
-        UserStore us = new UserStore(new IdmLightSimpleConnectionProvider(new IdmLightConfigBuilder().build()));
+        UserStore us = new UserStore(
+                new IdmLightSimpleConnectionProvider(new IdmLightConfigBuilder().dbUser("foo").dbPwd("bar").build()));
         Domain domain = h2Store.createDomain("sdn", true);
         User user = h2Store.createUser("test", "pass", domain.getDomainid(), "desc", "email", true, "SALT");
 
index 837ad012977712821d29ff03921f08820b37f020..9ae8aa332b9e3c263cd73e6808187943b68d5a0e 100644 (file)
@@ -20,7 +20,7 @@ public class IdmLightConfigTest {
 
     @Test
     public void testDefaults() {
-        IdmLightConfig config = new IdmLightConfigBuilder().build();
+        IdmLightConfig config = new IdmLightConfigBuilder().dbUser("foo").dbPwd("bar").build();
         assertThat(config.getDbDriver()).isEqualTo("org.h2.Driver");
         assertThat(config.getDbConnectionString()).isEqualTo("jdbc:h2:./data/idmlight.db");
         assertThat(config.getDbUser()).isEqualTo("foo");
@@ -31,6 +31,7 @@ public class IdmLightConfigTest {
     @Test
     public void testCustomDirectory() {
         IdmLightConfigBuilder builder = new IdmLightConfigBuilder();
+        builder.dbUser("foo").dbPwd("bar");
         builder.dbDirectory("target");
         IdmLightConfig config = builder.build();
         assertThat(config.getDbConnectionString()).isEqualTo("jdbc:h2:target/idmlight.db");
@@ -39,6 +40,7 @@ public class IdmLightConfigTest {
     @Test
     public void testCustomConnectionString() {
         IdmLightConfigBuilder builder = new IdmLightConfigBuilder();
+        builder.dbUser("foo").dbPwd("bar");
         builder.dbConnectionString("jdbc:mysql://localhost/test");
         IdmLightConfig config = builder.build();
         assertThat(config.getDbConnectionString()).isEqualTo("jdbc:mysql://localhost/test");
index c104da6b391a0819fa30d9fe1ac7374a9760c5a2..1afafc2d41f4a6d1502c2d6c7e17d52f327ad7e1 100644 (file)
@@ -5,7 +5,6 @@
  * 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.idm.persistence;
 
 import java.util.ArrayList;
@@ -14,7 +13,6 @@ import java.util.List;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
-import org.opendaylight.aaa.AAAShiroProvider;
 import org.opendaylight.aaa.api.IDMStoreException;
 import org.opendaylight.aaa.api.IIDMStore;
 import org.opendaylight.aaa.api.PasswordCredentials;
@@ -32,10 +30,11 @@ import org.opendaylight.aaa.shiro.idm.IdmLightProxy;
 */
 public class PasswordHashTest {
 
+    private IIDMStore store;
+
     @Before
     public void before() throws IDMStoreException {
-        IIDMStore store = Mockito.mock(IIDMStore.class);
-        AAAShiroProvider.setIdmStore(store);
+        store = Mockito.mock(IIDMStore.class);
         Domain domain = new Domain();
         domain.setName("sdn");
         domain.setDomainid("sdn");
@@ -72,7 +71,7 @@ public class PasswordHashTest {
 
     @Test
     public void testPasswordHash() {
-        IdmLightProxy proxy = new IdmLightProxy();
+        IdmLightProxy proxy = new IdmLightProxy(store);
         proxy.authenticate(new Creds());
     }
 
index f95c6134fd08c3fc68bbca891b4cd71032e45934..31f9028cab289dc6bfe575a98fdec19dad04a63c 100644 (file)
@@ -15,7 +15,6 @@ import com.sun.jersey.test.framework.WebAppDescriptor;
 import org.junit.Before;
 import org.opendaylight.aaa.api.StoreBuilder;
 import org.opendaylight.aaa.shiro.idm.IdmLightApplication;
-import org.opendaylight.aaa.AAAShiroProvider;
 import org.slf4j.bridge.SLF4JBridgeHandler;
 
 public abstract class HandlerTest extends JerseyTest {
@@ -41,6 +40,5 @@ public abstract class HandlerTest extends JerseyTest {
         SLF4JBridgeHandler.install();
         super.setUp();
         new StoreBuilder(testStore).init();
-        AAAShiroProvider.setIdmStore(testStore);
     }
 }
index 0f1253951b6e43c1d72dca93e795afd3c00532d1..6948b2475f3fe423c327aee902e6bb3e5bca317d 100644 (file)
@@ -5,17 +5,14 @@
  * 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.hamcrest.Matchers.arrayContaining;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.junit.Assert.assertThat;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.same;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -40,18 +37,17 @@ import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Mock;
-import org.mockito.Spy;
+import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.opendaylight.aaa.provider.GsonProvider;
-import org.opendaylight.aaa.AAAShiroProvider;
 import org.opendaylight.aaa.api.shiro.principal.ODLPrincipal;
 import org.opendaylight.aaa.cert.api.ICertificateManager;
+import org.opendaylight.aaa.provider.GsonProvider;
 import org.opendaylight.aaa.shiro.keystone.domain.KeystoneAuth;
 import org.opendaylight.aaa.shiro.keystone.domain.KeystoneToken;
 import org.opendaylight.aaa.shiro.realm.util.http.SimpleHttpClient;
 import org.opendaylight.aaa.shiro.realm.util.http.SimpleHttpRequest;
 import org.opendaylight.aaa.shiro.realm.util.http.UntrustedSSL;
-import org.osgi.service.http.HttpService;
+import org.opendaylight.aaa.shiro.web.env.ThreadLocals;
 
 @RunWith(MockitoJUnitRunner.class)
 public class KeystoneAuthRealmTest {
@@ -83,14 +79,15 @@ public class KeystoneAuthRealmTest {
     @Captor
     private ArgumentCaptor<KeystoneAuth> keystoneAuthArgumentCaptor;
 
-    @Spy
     private KeystoneAuthRealm keystoneAuthRealm;
 
     private KeystoneToken.Token ksToken;
 
     @Before
     public void setup() throws MalformedURLException, URISyntaxException {
-        AAAShiroProvider.newInstance(null, null, null, null, mock(HttpService.class), null, null, null, null, null);
+        ThreadLocals.CERT_MANAGER_TL.set(certificateManager);
+
+        keystoneAuthRealm = Mockito.spy(new KeystoneAuthRealm());
 
         final String testUrl = "http://example.com";
         // a token for a user without roles
index a770dee131c4292ff992898bdcfcc59c88d419ac..d7e27b0bd8e093575e1a89840775d7cfe9ab671d 100644 (file)
@@ -27,7 +27,7 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.shiro.subject.Subject;
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.aaa.AAAShiroProvider;
+import org.opendaylight.aaa.shiro.web.env.ThreadLocals;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
@@ -35,7 +35,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.aaa.rev1
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.aaa.rev161214.http.authorization.Policies;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.aaa.rev161214.http.permission.Permissions;
 import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.osgi.service.http.HttpService;
 
 /**
  * Tests the Dynamic Authorization Filter.
@@ -44,7 +43,6 @@ public class MDSALDynamicAuthorizationFilterTest {
 
     @Before
     public void setup() {
-        AAAShiroProvider.newInstance(null, null, null, null, mock(HttpService.class), null, null, null, null, null);
     }
 
     // test helper method to generate some cool mdsal data
@@ -85,20 +83,6 @@ public class MDSALDynamicAuthorizationFilterTest {
         return dataBroker;
     }
 
-    @Test
-    public void testIsAccessAllowed() throws Exception {
-        //
-        // Test Setup:
-        //
-        // Ensure that the base isAccessAllowed(...) method calls the static helper method.
-        final MDSALDynamicAuthorizationFilter filter = mock(MDSALDynamicAuthorizationFilter.class);
-        when(filter.isAccessAllowed(any(), any(), any(), any())).thenReturn(true);
-        when(filter.isAccessAllowed(any(), any(), any())).thenCallRealMethod();
-        assertTrue(filter.isAccessAllowed(null, null, null));
-        when(filter.isAccessAllowed(any(), any(), any(), any())).thenReturn(false);
-        assertFalse(filter.isAccessAllowed(null, null, null));
-    }
-
     @Test
     public void testGetHttpAuthzContainer() throws Exception {
         //
@@ -120,6 +104,7 @@ public class MDSALDynamicAuthorizationFilterTest {
         //
         // Test Setup: No rules are added to the HttpAuthorization container.  Open access should be allowed.
         final Subject subject = mock(Subject.class);
+        ThreadLocals.DATABROKER_TL.set(getTestData());
         final MDSALDynamicAuthorizationFilter filter = new MDSALDynamicAuthorizationFilter() {
             @Override
             protected Subject getSubject(final ServletRequest request, final ServletResponse servletResponse) {
@@ -142,7 +127,7 @@ public class MDSALDynamicAuthorizationFilterTest {
         //
         // Ensure that access is allowed since no data is returned from the MDSAL read.
         // This is through making sure the Optional is not present.
-        assertTrue(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertTrue(filter.isAccessAllowed(request, null, null));
 
         //
         // Same as above, but with an empty policy list returned.
@@ -152,22 +137,14 @@ public class MDSALDynamicAuthorizationFilterTest {
         when(httpAuthorization.getPolicies()).thenReturn(policies);
         when(dataObjectOptional.isPresent()).thenReturn(true);
         when(dataObjectOptional.get()).thenReturn(httpAuthorization);
-        assertTrue(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertTrue(filter.isAccessAllowed(request, null, null));
     }
 
     @Test
     public void testMDSALExceptionDuringRead() throws Exception {
-        //
         // Test Setup: No rules are added to the HttpAuthorization container.  The MDSAL read
         // is instructed to return an immediateFailedCheckedFuture, to emulate an error in reading
         // the Data Store.
-        final Subject subject = mock(Subject.class);
-        final MDSALDynamicAuthorizationFilter filter = new MDSALDynamicAuthorizationFilter() {
-            @Override
-            protected Subject getSubject(final ServletRequest request, final ServletResponse servletResponse) {
-                return subject;
-            }
-        };
 
         final HttpServletRequest request = mock(HttpServletRequest.class);
         when(request.getRequestURI()).thenReturn("abc");
@@ -182,9 +159,17 @@ public class MDSALDynamicAuthorizationFilterTest {
         final DataBroker dataBroker = mock(DataBroker.class);
         when(dataBroker.newReadOnlyTransaction()).thenReturn(rot);
 
-        //
+        final Subject subject = mock(Subject.class);
+        ThreadLocals.DATABROKER_TL.set(dataBroker);
+        final MDSALDynamicAuthorizationFilter filter = new MDSALDynamicAuthorizationFilter() {
+            @Override
+            protected Subject getSubject(final ServletRequest request, final ServletResponse servletResponse) {
+                return subject;
+            }
+        };
+
         // Ensure that if an error occurs while reading MD-SAL that access is denied.
-        assertFalse(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertFalse(filter.isAccessAllowed(request, null, null));
     }
 
     @Test
@@ -196,7 +181,7 @@ public class MDSALDynamicAuthorizationFilterTest {
         // A Rule is added to match /** allowing HTTP PUT for the admin role.
         // All other Methods are considered unauthorized.
         final Subject subject = mock(Subject.class);
-        final DataBroker dataBroker = getTestData();
+        ThreadLocals.DATABROKER_TL.set(getTestData());
         final MDSALDynamicAuthorizationFilter filter = new MDSALDynamicAuthorizationFilter() {
             @Override
             protected Subject getSubject(final ServletRequest request, final ServletResponse servletResponse) {
@@ -215,21 +200,21 @@ public class MDSALDynamicAuthorizationFilterTest {
         // Make a PUT HTTP request from a Subject with the admin role.  The request URL does not match,
         // since "abc" does not start with a "/" character.  Since no rule exists for this particular request,
         // then access should be allowed.
-        assertTrue(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertTrue(filter.isAccessAllowed(request, null, null));
 
         //
         // Test Case 2:
         //
         // Repeat of the above against a matching endpoint.  Access should be allowed.
         when(request.getRequestURI()).thenReturn("/anotherexamplethatshouldwork");
-        assertTrue(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertTrue(filter.isAccessAllowed(request, null, null));
 
         //
         // Test Case 3:
         //
         // Repeat of the above request against a more complex endpoint.  Access should be allowed.
         when(request.getRequestURI()).thenReturn("/auth/v1/users");
-        assertTrue(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertTrue(filter.isAccessAllowed(request, null, null));
 
         //
         // Test Case 4:
@@ -237,7 +222,7 @@ public class MDSALDynamicAuthorizationFilterTest {
         // Negative test case-- ensure that when an unallowed method (POST) is tried with an otherwise
         // allowable request, that access is denied.
         when(request.getMethod()).thenReturn("Post");
-        assertFalse(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertFalse(filter.isAccessAllowed(request, null, null));
 
         //
         // Test Case 5:
@@ -246,7 +231,7 @@ public class MDSALDynamicAuthorizationFilterTest {
         // request, that acess is denied.
         when(request.getMethod()).thenReturn("Put");
         when(subject.hasRole("admin")).thenReturn(false);
-        assertFalse(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertFalse(filter.isAccessAllowed(request, null, null));
     }
 
     @Test
@@ -297,6 +282,7 @@ public class MDSALDynamicAuthorizationFilterTest {
         when(dataBroker.newReadOnlyTransaction()).thenReturn(rot);
 
         final Subject subject = mock(Subject.class);
+        ThreadLocals.DATABROKER_TL.set(dataBroker);
         final MDSALDynamicAuthorizationFilter filter = new MDSALDynamicAuthorizationFilter() {
             @Override
             protected Subject getSubject(final ServletRequest request, final ServletResponse servletResponse) {
@@ -313,7 +299,7 @@ public class MDSALDynamicAuthorizationFilterTest {
         // Test Case 1:
         //
         // In the setup, two rules were added.  First, make sure that the first rule is working.
-        assertTrue(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertTrue(filter.isAccessAllowed(request, null, null));
 
         //
         // Test Case 2:
@@ -321,11 +307,11 @@ public class MDSALDynamicAuthorizationFilterTest {
         // Both rules would technically match the input request URI.  We want to make sure that
         // order is respected.  We do this by ensuring access is granted (i.e., the first rule is matched).
         when(request.getRequestURI()).thenReturn("/specialendpoint");
-        assertTrue(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertTrue(filter.isAccessAllowed(request, null, null));
         when(request.getRequestURI()).thenReturn("/specialendpoint/");
-        assertTrue(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertTrue(filter.isAccessAllowed(request, null, null));
         when(request.getRequestURI()).thenReturn("/specialendpoint/somewhatextended");
-        assertTrue(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertTrue(filter.isAccessAllowed(request, null, null));
 
         //
         // Test Case 3:
@@ -336,13 +322,13 @@ public class MDSALDynamicAuthorizationFilterTest {
         policiesList = Lists.newArrayList(innerPolicies2, innerPolicies);
         when(policies.getPolicies()).thenReturn(policiesList);
         when(request.getRequestURI()).thenReturn("/abc");
-        assertTrue(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertTrue(filter.isAccessAllowed(request, null, null));
         when(request.getRequestURI()).thenReturn("/specialendpoint");
-        assertFalse(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertFalse(filter.isAccessAllowed(request, null, null));
         when(request.getRequestURI()).thenReturn("/specialendpoint/");
-        assertFalse(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertFalse(filter.isAccessAllowed(request, null, null));
         when(request.getRequestURI()).thenReturn("/specialendpoint/somewhatextended");
-        assertFalse(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertFalse(filter.isAccessAllowed(request, null, null));
     }
 
     @Test
@@ -384,6 +370,7 @@ public class MDSALDynamicAuthorizationFilterTest {
         when(dataBroker.newReadOnlyTransaction()).thenReturn(rot);
 
         final Subject subject = mock(Subject.class);
+        ThreadLocals.DATABROKER_TL.set(dataBroker);
         final MDSALDynamicAuthorizationFilter filter = new MDSALDynamicAuthorizationFilter() {
             @Override
             protected Subject getSubject(final ServletRequest request, final ServletResponse servletResponse) {
@@ -397,9 +384,9 @@ public class MDSALDynamicAuthorizationFilterTest {
         when(subject.hasRole("admin")).thenReturn(false);
         when(subject.hasRole("user")).thenReturn(true);
 
-        assertFalse(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertFalse(filter.isAccessAllowed(request, null, null));
         when(request.getMethod()).thenReturn("Get");
-        assertTrue(filter.isAccessAllowed(request, null, null, dataBroker));
+        assertTrue(filter.isAccessAllowed(request, null, null));
 
     }
 }