/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.core.security.userstore; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.Assert; import com.enonic.cms.api.plugin.ext.userstore.RemoteUserStore; import com.enonic.cms.core.security.userstore.connector.UserStoreConnector; import com.enonic.cms.core.security.userstore.connector.config.UserStoreConnectorConfig; import com.enonic.cms.core.security.userstore.connector.config.UserStoreConnectorConfigLoader; import com.enonic.cms.core.security.userstore.connector.local.LocalUserStoreConnector; import com.enonic.cms.core.security.userstore.connector.remote.RemoteUserStoreConnector; import com.enonic.cms.core.security.userstore.connector.remote.RemoteUserStoreManager; import com.enonic.cms.core.time.TimeService; import com.enonic.cms.store.dao.GroupDao; import com.enonic.cms.store.dao.UserDao; import com.enonic.cms.store.dao.UserStoreDao; @Component public final class UserStoreConnectorManagerImpl implements UserStoreConnectorManager, InitializingBean { @Autowired private UserStoreConnectorConfigLoader userStoreConnectorConfigLoader; @Autowired private RemoteUserStoreManager remoteUserStoreFactory; @Autowired private UserDao userDao; @Autowired private GroupDao groupDao; @Autowired private GroupStorerFactory groupStorerFactory; @Autowired private UserStorerFactory userStorerFactory; @Autowired private TimeService timeService; @Autowired private UserStoreDao userStoreDao; private final Map<UserStoreKey, RemoteUserStoreConnector> remoteUSConnectorMap = Collections.synchronizedMap( new HashMap<UserStoreKey, RemoteUserStoreConnector>() ); private final Map<UserStoreKey, LocalUserStoreConnector> localUSConnectorMap = Collections.synchronizedMap( new HashMap<UserStoreKey, LocalUserStoreConnector>() ); public Map<String, UserStoreConnectorConfig> getUserStoreConnectorConfigs() { return userStoreConnectorConfigLoader.getAllUserStoreConnectorConfigs(); } public UserStoreConnectorConfig getUserStoreConnectorConfig( final String configName ) { return userStoreConnectorConfigLoader.getUserStoreConnectorConfig( configName ); } public UserStoreConnectorConfig getUserStoreConnectorConfig( final UserStoreKey userStoreKey ) { UserStoreEntity userStore = userStoreDao.findByKey( userStoreKey ); if ( userStore.isLocal() ) { throw new IllegalArgumentException( "Local user stores does not have a connector config" ); } return userStoreConnectorConfigLoader.getUserStoreConnectorConfig( userStore.getConnectorName() ); } @Override public void invalidateCachedConfig( UserStoreKey userStoreKey ) { remoteUSConnectorMap.remove( userStoreKey ); localUSConnectorMap.remove( userStoreKey ); } public UserStoreConnector getUserStoreConnector( final UserStoreKey userStoreKey ) { return doGetUSConnectorBykey( userStoreKey ); } public RemoteUserStoreConnector getRemoteUserStoreConnector( final UserStoreKey userStoreKey ) { UserStoreConnector comm = doGetUSConnectorBykey( userStoreKey ); if ( comm instanceof RemoteUserStoreConnector ) { return (RemoteUserStoreConnector) comm; } //throw new IllegalArgumentException( "Given userStoreKey does not reference a remote user store: " + userStoreKey ); return null; } private UserStoreConnector doGetUSConnector( final UserStoreEntity userStore ) { if ( userStore.isLocal() ) { return doGetLocalUserStoreConnector( userStore ); } return doGetRemoteUserStoreConnector( userStore ); } private synchronized RemoteUserStoreConnector doGetRemoteUserStoreConnector( final UserStoreEntity userStore ) { RemoteUserStoreConnector connector = remoteUSConnectorMap.get( userStore.getKey() ); if ( connector != null ) { boolean connectorNameSame = connector.getConnectorName().equals( userStore.getConnectorName() ); boolean userStoreNameSame = connector.getUserStoreName().equals( userStore.getName() ); if ( connectorNameSame && userStoreNameSame ) { return connector; } //Userstore name or connector name has changed - remove obsolete connector for userstore remoteUSConnectorMap.remove( userStore.getKey() ); } connector = createRemoteUserStoreConnector( userStore ); remoteUSConnectorMap.put( userStore.getKey(), connector ); return connector; } private synchronized LocalUserStoreConnector doGetLocalUserStoreConnector( final UserStoreEntity userStore ) { LocalUserStoreConnector connector = localUSConnectorMap.get( userStore.getKey() ); if ( connector != null ) { boolean connectorNameSame = connector.getConnectorName().equals( userStore.getConnectorName() ); boolean userStoreNameSame = connector.getUserStoreName().equals( userStore.getName() ); if ( connectorNameSame && userStoreNameSame ) { return connector; } //Userstore name or connector name has changed - remove obsolete connector for userstore localUSConnectorMap.remove( userStore.getKey() ); } connector = createLocalUserStoreUserStoreConnector( userStore ); localUSConnectorMap.put( userStore.getKey(), connector ); return connector; } private RemoteUserStoreConnector createRemoteUserStoreConnector( final UserStoreEntity userStore ) { final UserStoreConnectorConfig connectorConfig = userStoreConnectorConfigLoader.getUserStoreConnectorConfig( userStore.getConnectorName() ); final RemoteUserStore remoteUserStorePlugin = remoteUserStoreFactory.create( connectorConfig.getPluginType(), connectorConfig.getPluginProperties() ); final RemoteUserStoreConnector connector = new RemoteUserStoreConnector( userStore.getKey(), userStore.getName(), userStore.getConnectorName() ); connector.setTimeService( timeService ); connector.setRemoteUserStorePlugin( remoteUserStorePlugin ); connector.setUserDao( userDao ); connector.setGroupDao( groupDao ); connector.setGroupStorerFactory( groupStorerFactory ); connector.setUserStorerFactory( userStorerFactory ); connector.setUserStoreDao( userStoreDao ); connector.setConnectorConfig( connectorConfig ); connector.setUserStoreConfig( userStore.getConfig() ); return connector; } private LocalUserStoreConnector createLocalUserStoreUserStoreConnector( final UserStoreEntity userStore ) { final LocalUserStoreConnector connector = new LocalUserStoreConnector( userStore.getKey(), userStore.getName() ); connector.setUserDao( userDao ); connector.setGroupDao( groupDao ); connector.setGroupStorerFactory( groupStorerFactory ); connector.setUserStorerFactory( userStorerFactory ); connector.setUserStoreDao( userStoreDao ); return connector; } private UserStoreConnector doGetUSConnectorBykey( final UserStoreKey userStoreKey ) { Assert.notNull( userStoreKey, "userStoreKey cannot be null" ); UserStoreEntity userStore = this.userStoreDao.findByKey( userStoreKey ); if ( userStore != null ) { return doGetUSConnector( userStore ); } throw new IllegalArgumentException( "User store [" + userStoreKey + "] not found" ); } @Override public void afterPropertiesSet() throws Exception { this.remoteUserStoreFactory.setRefreshCallback( new Runnable() { @Override public void run() { remoteUSConnectorMap.clear(); } } ); } }