/** * Copyright 2005-2016 hdiv.org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.hdiv.config.annotation; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.hdiv.application.ApplicationHDIV; import org.hdiv.application.IApplication; import org.hdiv.config.HDIVConfig; import org.hdiv.config.StartPage; import org.hdiv.config.annotation.ValidationConfigurer.ValidationConfig; import org.hdiv.config.annotation.ValidationConfigurer.ValidationConfig.EditableValidationConfigurer; import org.hdiv.config.annotation.builders.SecurityConfigBuilder; import org.hdiv.config.validations.DefaultValidationParser; import org.hdiv.config.validations.DefaultValidationParser.ValidationParam; import org.hdiv.context.RequestContextFactory; import org.hdiv.context.RequestContextFactoryImpl; import org.hdiv.dataComposer.DataComposerFactory; import org.hdiv.dataValidator.DataValidator; import org.hdiv.dataValidator.IDataValidator; import org.hdiv.dataValidator.ValidationResult; import org.hdiv.filter.DefaultValidationContextFactory; import org.hdiv.filter.DefaultValidatorErrorHandler; import org.hdiv.filter.IValidationHelper; import org.hdiv.filter.ValidationContextFactory; import org.hdiv.filter.ValidatorErrorHandler; import org.hdiv.filter.ValidatorHelperRequest; import org.hdiv.idGenerator.PageIdGenerator; import org.hdiv.idGenerator.RandomGuidUidGenerator; import org.hdiv.idGenerator.SequentialPageIdGenerator; import org.hdiv.idGenerator.UidGenerator; import org.hdiv.init.DefaultRequestInitializer; import org.hdiv.init.DefaultServletContextInitializer; import org.hdiv.init.DefaultSessionInitializer; import org.hdiv.init.RequestInitializer; import org.hdiv.init.ServletContextInitializer; import org.hdiv.init.SessionInitializer; import org.hdiv.logs.IUserData; import org.hdiv.logs.Logger; import org.hdiv.logs.UserData; import org.hdiv.regex.PatternMatcher; import org.hdiv.regex.PatternMatcherFactory; import org.hdiv.session.ISession; import org.hdiv.session.IStateCache; import org.hdiv.session.SessionHDIV; import org.hdiv.session.StateCache; import org.hdiv.state.StateUtil; import org.hdiv.state.scope.AppStateScope; import org.hdiv.state.scope.DefaultStateScopeManager; import org.hdiv.state.scope.StateScope; import org.hdiv.state.scope.StateScopeManager; import org.hdiv.state.scope.UserSessionStateScope; import org.hdiv.urlProcessor.BasicUrlProcessor; import org.hdiv.urlProcessor.FormUrlProcessor; import org.hdiv.urlProcessor.LinkUrlProcessor; import org.hdiv.validator.DefaultEditableDataValidationProvider; import org.hdiv.validator.DefaultValidationRepository; import org.hdiv.validator.EditableDataValidationProvider; import org.hdiv.validator.IValidation; import org.hdiv.validator.Validation; import org.hdiv.validator.ValidationRepository; import org.hdiv.validator.ValidationTarget; import org.springframework.beans.factory.BeanInitializationException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; /** * Main abstract class for {@link Configuration} support. Creates all internal bean instances. * * @since 3.0.0 */ public abstract class AbstractHdivWebSecurityConfiguration { /** * Override this method to configure HDIV * * @param securityConfigBuilder {@link SecurityConfigBuilder} instance * @see SecurityConfigBuilder */ protected void configure(final SecurityConfigBuilder securityConfigBuilder) { } /** * Override this method to add exclusions to the validation process. * * @param registry {@link ExclusionRegistry} instance * @see ExclusionRegistry */ protected void addExclusions(final ExclusionRegistry registry) { } /** * Override this method to add long living pages to the application. * * @param registry {@link LongLivingPagesRegistry} instance * @see LongLivingPagesRegistry */ protected void addLongLivingPages(final LongLivingPagesRegistry registry) { } /** * Override this method to add editable validation rules. * * @param registry {@link RuleRegistry} instance * @see RuleRegistry */ protected void addRules(final RuleRegistry registry) { } /** * Override this method to add editable validations to the application. * * @param validationConfigurer {@link ValidationConfigurer} instance * @see ValidationConfigurer */ protected void configureEditableValidation(final ValidationConfigurer validationConfigurer) { } @Bean public HDIVConfig hdivConfig() { SecurityConfigBuilder securityConfigBuilder = securityConfigBuilder(); configure(securityConfigBuilder); HDIVConfig config = securityConfigBuilder.build(); config.setEditableDataValidationProvider(editableDataValidationProvider()); // User configured exclusions ExclusionRegistry exclusionRegistry = new ExclusionRegistry(patternMatcherFactory()); addExclusions(exclusionRegistry); // Start Pages List<StartPage> exclusions = exclusionRegistry.getUrlExclusions(); config.setUserStartPages(exclusions); // StartParameters List<String> paramExclusions = exclusionRegistry.getParamExclusions(); config.setUserStartParameters(paramExclusions); // ParamsWithoutValidation Map<String, List<String>> paramsWithoutValidation = exclusionRegistry.getParamExclusionsForUrl(); config.setParamsWithoutValidation(paramsWithoutValidation); // Long living pages LongLivingPagesRegistry longLivingPagesRegistry = new LongLivingPagesRegistry(); addLongLivingPages(longLivingPagesRegistry); Map<String, String> longLivingPages = longLivingPagesRegistry.getLongLivingPages(); config.setLongLivingPages(longLivingPages); return config; } @Bean public RequestContextFactory requestContextFactory() { return new RequestContextFactoryImpl(); } @Bean protected SecurityConfigBuilder securityConfigBuilder() { return new SecurityConfigBuilder(patternMatcherFactory()); } @Bean public IApplication securityApplication() { return new ApplicationHDIV(); } @Bean public ValidationResult validationResult() { return new ValidationResult(); } @Bean public PatternMatcherFactory patternMatcherFactory() { return new PatternMatcherFactory(); } @Bean public UidGenerator uidGenerator() { return new RandomGuidUidGenerator(); } @Bean @Scope(BeanDefinition.SCOPE_PROTOTYPE) public PageIdGenerator pageIdGenerator() { return new SequentialPageIdGenerator(); } @Bean public IUserData securityUserData() { return new UserData(); } @Bean public Logger securityLogger() { return new Logger(); } @Bean public ValidatorErrorHandler validatorErrorHandler() { DefaultValidatorErrorHandler validatorErrorHandler = new DefaultValidatorErrorHandler(); validatorErrorHandler.setConfig(hdivConfig()); return validatorErrorHandler; } @Bean @Scope(BeanDefinition.SCOPE_PROTOTYPE) public IStateCache stateCache() { SecurityConfigBuilder builder = securityConfigBuilder(); int maxPagesPerSession = builder.getMaxPagesPerSession(); StateCache stateCache = new StateCache(); if (maxPagesPerSession > 0) { stateCache.setMaxSize(maxPagesPerSession); } return stateCache; } @Bean public ISession securitySession() { return new SessionHDIV(); } @Bean public StateUtil stateUtil() { StateUtil stateUtil = new StateUtil(); stateUtil.setConfig(hdivConfig()); stateUtil.setSession(securitySession()); stateUtil.setStateScopeManager(stateScopeManager()); stateUtil.init(); return stateUtil; } @Bean public IDataValidator dataValidator() { DataValidator dataValidator = new DataValidator(); dataValidator.setConfig(hdivConfig()); return dataValidator; } @Bean public StateScopeManager stateScopeManager() { List<StateScope> stateScopes = new ArrayList<StateScope>(); stateScopes.add(userSessionStateScope()); stateScopes.add(appStateScope()); return new DefaultStateScopeManager(stateScopes); } @Bean public UserSessionStateScope userSessionStateScope() { UserSessionStateScope scope = new UserSessionStateScope(); scope.setSession(securitySession()); return scope; } @Bean public AppStateScope appStateScope() { return new AppStateScope(); } @Bean public DataComposerFactory dataComposerFactory() { DataComposerFactory dataComposerFactory = new DataComposerFactory(); dataComposerFactory.setConfig(hdivConfig()); dataComposerFactory.setSession(securitySession()); dataComposerFactory.setStateUtil(stateUtil()); dataComposerFactory.setUidGenerator(uidGenerator()); dataComposerFactory.setStateScopeManager(stateScopeManager()); return dataComposerFactory; } @Bean public IValidationHelper requestValidationHelper() { ValidatorHelperRequest validatorHelperRequest = new ValidatorHelperRequest(); validatorHelperRequest.setStateUtil(stateUtil()); validatorHelperRequest.setHdivConfig(hdivConfig()); validatorHelperRequest.setSession(securitySession()); validatorHelperRequest.setDataValidator(dataValidator()); validatorHelperRequest.setUrlProcessor(basicUrlProcessor()); validatorHelperRequest.setDataComposerFactory(dataComposerFactory()); validatorHelperRequest.setStateScopeManager(stateScopeManager()); validatorHelperRequest.init(); return validatorHelperRequest; } @Bean public RequestInitializer securityRequestInitializer() { DefaultRequestInitializer requestInitializer = new DefaultRequestInitializer(); requestInitializer.setConfig(hdivConfig()); requestInitializer.setSession(securitySession()); return requestInitializer; } @Bean public ServletContextInitializer securityServletContextInitializer() { DefaultServletContextInitializer servletContextInitializer = new DefaultServletContextInitializer(); servletContextInitializer.setConfig(hdivConfig()); servletContextInitializer.setApplication(securityApplication()); servletContextInitializer.setFormUrlProcessor(formUrlProcessor()); servletContextInitializer.setLinkUrlProcessor(linkUrlProcessor()); return servletContextInitializer; } @Bean public SessionInitializer securitySessionInitializer() { DefaultSessionInitializer sessionInitializer = new DefaultSessionInitializer(); sessionInitializer.setConfig(hdivConfig()); return sessionInitializer; } @Bean public LinkUrlProcessor linkUrlProcessor() { LinkUrlProcessor linkUrlProcessor = new LinkUrlProcessor(); linkUrlProcessor.setConfig(hdivConfig()); return linkUrlProcessor; } @Bean public FormUrlProcessor formUrlProcessor() { FormUrlProcessor formUrlProcessor = new FormUrlProcessor(); formUrlProcessor.setConfig(hdivConfig()); return formUrlProcessor; } @Bean public BasicUrlProcessor basicUrlProcessor() { BasicUrlProcessor basicUrlProcessor = new BasicUrlProcessor(); basicUrlProcessor.setConfig(hdivConfig()); return basicUrlProcessor; } @Bean public EditableDataValidationProvider editableDataValidationProvider() { DefaultEditableDataValidationProvider provider = new DefaultEditableDataValidationProvider(); provider.setValidationRepository(editableValidationRepository()); return provider; } @Bean public ValidationRepository editableValidationRepository() { // Default rules List<IValidation> defaultRules = getDefaultRules(); // Custom rules Map<String, IValidation> customRules = getCustomRules(); // Validation configuration Map<ValidationTarget, List<IValidation>> validationsData = getValidationsData(defaultRules, customRules); DefaultValidationRepository repository = new DefaultValidationRepository(); repository.setValidations(validationsData); repository.setDefaultValidations(defaultRules); return repository; } @Bean public ValidationContextFactory validationContextFactory() { return new DefaultValidationContextFactory(); } protected List<IValidation> getDefaultRules() { // Load validations from xml DefaultValidationParser parser = new DefaultValidationParser(); parser.readDefaultValidations(); List<Map<ValidationParam, String>> validations = parser.getValidations(); List<IValidation> defaultRules = new ArrayList<IValidation>(); for (Map<ValidationParam, String> validation : validations) { // Map contains validation id and regex extracted from the xml String id = validation.get(ValidationParam.ID); String regex = validation.get(ValidationParam.REGEX); // Create bean for the validation Validation validationBean = new Validation(); validationBean.setName(id); validationBean.setDefaultValidation(true); validationBean.setRejectedPattern(regex); defaultRules.add(validationBean); } return defaultRules; } protected Map<String, IValidation> getCustomRules() { RuleRegistry registry = new RuleRegistry(); addRules(registry); return registry.getRules(); } protected Map<ValidationTarget, List<IValidation>> getValidationsData(final List<IValidation> defaultRules, final Map<String, IValidation> customRules) { PatternMatcherFactory patternMatcherFactory = patternMatcherFactory(); ValidationConfigurer validationConfigurer = new ValidationConfigurer(); configureEditableValidation(validationConfigurer); List<ValidationConfig> validationConfigs = validationConfigurer.getValidationConfigs(); Map<ValidationTarget, List<IValidation>> validationsData = new LinkedHashMap<ValidationTarget, List<IValidation>>(); for (ValidationConfig validationConfig : validationConfigs) { String urlPattern = validationConfig.getUrlPattern(); EditableValidationConfigurer editableValidationConfigurer = validationConfig.getEditableValidationConfigurer(); boolean useDefaultRules = editableValidationConfigurer.isDefaultRules(); List<String> selectedRules = editableValidationConfigurer.getRules(); List<String> selectedParams = editableValidationConfigurer.getParameters(); // Add selected rules List<IValidation> activeRules = new ArrayList<IValidation>(); for (String ruleName : selectedRules) { IValidation val = customRules.get(ruleName); if (val == null) { throw new BeanInitializationException("Rule with name '" + ruleName + "' not registered."); } activeRules.add(val); } // Add default rules if is required if (useDefaultRules) { activeRules.addAll(defaultRules); } // Create ValidationTarget object ValidationTarget target = new ValidationTarget(); if (urlPattern != null) { PatternMatcher urlMatcher = patternMatcherFactory.getPatternMatcher(urlPattern); target.setUrl(urlMatcher); } List<PatternMatcher> paramMatchers = new ArrayList<PatternMatcher>(); for (String param : selectedParams) { PatternMatcher matcher = patternMatcherFactory.getPatternMatcher(param); paramMatchers.add(matcher); } target.setParams(paramMatchers); validationsData.put(target, activeRules); } return validationsData; } }