package com.enonic.vertical.adminweb.wizard; import java.io.IOException; import java.io.ObjectInputStream; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.enonic.esl.containers.ExtendedMap; import com.enonic.esl.xml.XMLTool; import com.enonic.vertical.adminweb.VerticalAdminLogger; import com.enonic.vertical.engine.VerticalEngineException; import com.enonic.cms.framework.util.JDOMUtil; import com.enonic.cms.framework.xml.XMLDocument; import com.enonic.cms.framework.xml.XMLDocumentFactory; import com.enonic.cms.api.plugin.ext.userstore.UserStoreConfig; import com.enonic.cms.core.security.user.User; import com.enonic.cms.core.security.userstore.StoreNewUserStoreCommand; import com.enonic.cms.core.security.userstore.UpdateUserStoreCommand; import com.enonic.cms.core.security.userstore.UserStoreEntity; import com.enonic.cms.core.security.userstore.UserStoreKey; import com.enonic.cms.core.security.userstore.UserStoreService; import com.enonic.cms.core.security.userstore.UserStoreServiceImpl; import com.enonic.cms.core.security.userstore.UserStoreXmlCreator; import com.enonic.cms.core.security.userstore.config.UserStoreConfigParser; import com.enonic.cms.core.security.userstore.connector.config.UserStoreConnectorConfig; import com.enonic.cms.core.security.userstore.connector.config.UserStoreConnectorConfigXmlCreator; import com.enonic.cms.core.service.AdminService; public class CreateUpdateUserStoreWizard extends Wizard { @Autowired private transient UserStoreService userStoreService; private static final String ERROR_CONNECTOR = "20"; private static final String ERROR_XMLPARSING = "2"; private static final String ERROR_NAMEILLEGALCHARS = "19"; public CreateUpdateUserStoreWizard() { super(); } protected void initialize( AdminService admin, Document wizardConfigDoc ) throws WizardException { } private void readObject( ObjectInputStream in ) throws IOException, ClassNotFoundException { in.defaultReadObject(); this.userStoreService = UserStoreServiceImpl.INSTANCE; } protected boolean validateState( WizardState wizardState, HttpSession session, AdminService admin, ExtendedMap formItems ) { boolean state = true; final String userStoreType = formItems.getString( "userStoreType" ); String connectorName = null; if ( userStoreType.equals( "remote" ) ) { connectorName = formItems.getString( "remoteUserStoreConnector", null ); final String errorMessageConnector = verifyConnector( connectorName ); if ( errorMessageConnector != null ) { wizardState.addError( ERROR_CONNECTOR, "connector", errorMessageConnector ); state = false; } } if ( state ) { final String errorMessageConfig = verifyConfig( formItems.getString( "config", null ), connectorName ); if ( errorMessageConfig != null ) { wizardState.addError( ERROR_XMLPARSING, "config", errorMessageConfig ); state = false; } } final String userStoreName = formItems.getString( "name" ); final String userStoreNameRegExp = "[a-zA-Z0-9_-]+"; if ( !userStoreName.matches( userStoreNameRegExp ) ) { wizardState.addError( ERROR_NAMEILLEGALCHARS, "name" ); state = false; } return state; } protected boolean evaluate( WizardState wizardState, HttpSession session, AdminService admin, ExtendedMap formItems, String testCondition ) throws WizardException { return true; } protected void processWizardData( WizardState wizardState, HttpSession session, AdminService admin, ExtendedMap formItems, User user, Document dataDoc ) throws WizardException, VerticalEngineException { if ( StringUtils.isNotEmpty( formItems.getString( "key", null ) ) ) { updateUserStore( formItems, user, userStoreService ); } else { storeNewUserStore( formItems, user, userStoreService ); } } protected void appendCustomData( WizardState wizardState, HttpSession session, AdminService admin, ExtendedMap formItems, ExtendedMap parameters, User user, Document dataconfigDoc, Document wizarddataDoc ) throws WizardException { Element wizarddataElem = wizarddataDoc.getDocumentElement(); Step currentStep = wizardState.getCurrentStep(); if ( "step0".equals( currentStep.getName() ) ) { Map<String, UserStoreConnectorConfig> userStoreConnectorConfigs = userStoreService.getUserStoreConnectorConfigs(); if ( formItems.containsKey( "key" ) ) { int key = formItems.getInt( "key" ); final UserStoreXmlCreator userStoreXmlCreator = new UserStoreXmlCreator( userStoreConnectorConfigs ); UserStoreEntity userStore = userStoreService.getUserStore( new UserStoreKey( key ) ); XMLDocument userStoresXmlDoc = XMLDocumentFactory.create( userStoreXmlCreator.createUserStoresDocument( userStore ) ); wizarddataElem.appendChild( wizarddataDoc.importNode( userStoresXmlDoc.getAsDOMDocument().getDocumentElement(), true ) ); } // Default User Store Element defaultUserStoreElem = XMLTool.createElement( wizarddataElem, "defaultuserstore" ); UserStoreEntity defaultUserStore = userStoreService.getDefaultUserStore(); if ( defaultUserStore != null ) { defaultUserStoreElem.setAttribute( "key", defaultUserStore.getKey().toString() ); } wizarddataElem.appendChild( wizarddataDoc.importNode( defaultUserStoreElem, true ) ); // UserStore connector config names final XMLDocument userStoreConnectorConfigNamesXmlDoc = XMLDocumentFactory.create( UserStoreConnectorConfigXmlCreator.createUserStoreConnectorConfigsDocument( userStoreConnectorConfigs.values() ) ); wizarddataElem.appendChild( wizarddataDoc.importNode( userStoreConnectorConfigNamesXmlDoc.getAsDOMDocument().getDocumentElement(), true ) ); } else { String message = "Unknown step: {0}"; VerticalAdminLogger.error( message, currentStep.getName(), null ); } } protected void saveState( WizardState wizardState, HttpServletRequest request, HttpServletResponse response, AdminService admin, User user, ExtendedMap formItems ) throws WizardException { super.saveState( wizardState, request, response, admin, user, formItems ); // get step state document StepState stepState = wizardState.getCurrentStepState(); Document stepstateDoc = stepState.getStateDoc(); Element rootElem = stepstateDoc.getDocumentElement(); Step currentStep = wizardState.getCurrentStep(); if ( "step0".equals( currentStep.getName() ) ) { final Element userStoreElem = XMLTool.createElement( stepstateDoc, rootElem, "userstore" ); if ( formItems.containsKey( "key" ) ) { userStoreElem.setAttribute( "key", formItems.getString( "key" ) ); } userStoreElem.setAttribute( "name", formItems.getString( "name" ) ); userStoreElem.setAttribute( "default", formItems.getString( "defaultuserstore", "false" ) ); final String userStoreType = formItems.getString( "userStoreType" ); userStoreElem.setAttribute( "remote", userStoreType.equals( "remote" ) ? "true" : "false" ); if ( userStoreType.equals( "remote" ) ) { userStoreElem.setAttribute( "connector", formItems.getString( "remoteUserStoreConnector", null ) ); } XMLTool.createElement( stepstateDoc, userStoreElem, "configRaw", formItems.getString( "config", "" ) ); } else { String message = "Unknown step: {0}"; WizardLogger.errorWizard( message, currentStep ); } } private String verifyConnector( final String connectorName ) { try { userStoreService.verifyUserStoreConnector( connectorName ); } catch ( Exception e ) { return e.getMessage(); } return null; } private String verifyConfig( final String xmlConfigData, final String connectorName ) { try { org.jdom.Element configEl = null; if ( StringUtils.isNotEmpty( xmlConfigData.trim() ) ) { configEl = JDOMUtil.parseDocument( xmlConfigData ).getRootElement(); } final UserStoreConfig config = UserStoreConfigParser.parse( configEl, connectorName != null ); if ( connectorName != null ) { userStoreService.verifyUserStoreConnectorConfig( config, connectorName ); } } catch ( Exception e ) { return e.getMessage(); } return null; } private void updateUserStore( ExtendedMap formItems, User user, UserStoreService userStoreService ) { final UserStoreKey userStoreKey = new UserStoreKey( formItems.getString( "key" ) ); final boolean newDefaultUserStore = formItems.getBoolean( "defaultuserstore", false ); final String userStoreType = formItems.getString( "userStoreType" ); String connectorName = null; if ( userStoreType.equals( "remote" ) ) { connectorName = formItems.getString( "remoteUserStoreConnector", null ); } final String configXmlString = formItems.getString( "config", null ); UserStoreConfig config = new UserStoreConfig(); if ( configXmlString != null && configXmlString.trim().length() > 0 ) { config = UserStoreConfigParser.parse( XMLDocumentFactory.create( configXmlString ).getAsJDOMDocument().getRootElement(), connectorName != null ); } final UpdateUserStoreCommand command = new UpdateUserStoreCommand(); command.setUpdater( user.getKey() ); command.setKey( userStoreKey ); command.setName( formItems.getString( "name", null ) ); if ( newDefaultUserStore ) { command.setAsNewDefaultStore(); } command.setConnectorName( connectorName ); command.setConfig( config ); userStoreService.updateUserStore( command ); userStoreService.invalidateUserStoreCachedConfig( command.getKey() ); } private void storeNewUserStore( ExtendedMap formItems, User user, UserStoreService userStoreService ) { final String userStoreType = formItems.getString( "userStoreType" ); String connectorName = null; if ( userStoreType.equals( "remote" ) ) { connectorName = formItems.getString( "remoteUserStoreConnector", null ); } final String configXmlString = formItems.getString( "config", null ); UserStoreConfig config = new UserStoreConfig(); if ( configXmlString != null && configXmlString.trim().length() > 0 ) { config = UserStoreConfigParser.parse( XMLDocumentFactory.create( configXmlString ).getAsJDOMDocument().getRootElement(), connectorName != null ); } final StoreNewUserStoreCommand command = new StoreNewUserStoreCommand(); command.setStorer( user.getKey() ); command.setName( formItems.getString( "name", null ) ); command.setDefaultStore( formItems.getBoolean( "defaultuserstore", false ) ); command.setConnectorName( connectorName ); command.setConfig( config ); userStoreService.storeNewUserStore( command ); } }