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));
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;
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
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;
*/
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
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>
<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>
<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,
org.ops4j.pax.web.service,
org.h2.*,
</Import-Package>
- <Bundle-Activator>org.opendaylight.aaa.AAAShiroActivator</Bundle-Activator>
</instructions>
</configuration>
</plugin>
+++ /dev/null
-/*
- * 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));
- }
- }
-}
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;
/**
* 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;
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;
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,
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;
}
/**
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) {
* 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 {
*
* @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.
* 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;
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;
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;
private static final Logger LOG = LoggerFactory.getLogger(DomainHandler.class);
+ private final AAAShiroProvider provider;
+
+ public DomainHandler(AAAShiroProvider provider) {
+ this.provider = provider;
+ }
+
/**
* Extracts all domains.
*
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();
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();
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();
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);
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);
// 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();
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();
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();
// 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);
// 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();
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();
// 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();
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) {
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();
}
try {
- user = AAAShiroProvider.getInstance().getIdmStore().readUser(userId);
+ user = provider.getIdmStore().readUser(userId);
} catch (IDMStoreException e) {
LOG.error("StoreException", e);
IDMError idmerror = new IDMError();
}
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) {
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();
}
try {
- user = AAAShiroProvider.getInstance().getIdmStore().readUser(userId);
+ user = provider.getIdmStore().readUser(userId);
} catch (IDMStoreException e) {
LOG.error("StoreException", e);
IDMError idmerror = new IDMError();
}
try {
- role = AAAShiroProvider.getInstance().getIdmStore().readRole(roleId);
+ role = provider.getIdmStore().readRole(roleId);
} catch (IDMStoreException e) {
LOG.error("StoreException", e);
IDMError idmerror = new IDMError();
// 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();
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
* 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.
/**
*/
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();
}
}
* 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;
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;
new ConcurrentHashMap<PasswordCredentials, Claim>());
}
+ private final IIDMStore idmStore;
+
+ public IdmLightProxy(IIDMStore idmStore) {
+ this.idmStore = idmStore;
+ }
+
@Override
public Claim authenticate(PasswordCredentials creds) {
Preconditions.checkNotNull(creds);
}
}
- 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();
// 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");
}
// 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()
// 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());
}
@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();
}
}
* 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;
*/
@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.
*
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();
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();
.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();
// 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();
}
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();
}
* 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;
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;
*/
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.
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();
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;
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);
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();
}
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),
* 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;
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;
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);
.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());
}
});
}
* 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;
* 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);
}
}
- @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();
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;
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
* @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);
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");
}
}
* Adds debugging information surrounding creation of ODLJndiLdapRealm
*/
public ODLJndiLdapRealmAuthNOnly() {
- LOG.debug("Creating ODLJndiLdapRealmAuthNOnly");
+ LOG.info("ODLJndiLdapRealmAuthNOnly realm created");
}
/*
* 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;
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);
@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());
super.init();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException("Error obtaining AAAShiroProvider", e);
+ } finally {
+ ThreadLocals.DATABROKER_TL.remove();
+ ThreadLocals.CERT_MANAGER_TL.remove();
}
}
}
protected Class<?> determineWebEnvironmentClass(ServletContext servletContext) {
return KarafIniWebEnvironment.class;
}
-
}
--- /dev/null
+/*
+ * 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<>();
+}
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;
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())
<!-- 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>
<!-- 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>
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"/>
</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" />
<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" />
<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>
@Test
public void deleteDomainsTest() throws SQLException, Exception {
- DomainStore ds = new DomainStore(new IdmLightSimpleConnectionProvider(new IdmLightConfigBuilder().build()));
String domainId = "Testing12345";
// Run Test
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);
@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);
@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");
@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");
@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");
@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");
* 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;
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;
*/
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");
@Test
public void testPasswordHash() {
- IdmLightProxy proxy = new IdmLightProxy();
+ IdmLightProxy proxy = new IdmLightProxy(store);
proxy.authenticate(new Creds());
}
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 {
SLF4JBridgeHandler.install();
super.setUp();
new StoreBuilder(testStore).init();
- AAAShiroProvider.setIdmStore(testStore);
}
}
* 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;
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 {
@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
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;
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.
@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
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 {
//
//
// 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) {
//
// 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.
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");
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
// 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) {
// 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:
// 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:
// 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
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) {
// 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:
// 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:
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
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) {
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));
}
}