Details
Description
We need a way to override the private methods of org.onehippo.repository.update.GroovyUpdaterClassLoader.
Technical investigation
The relevant code we need to hook into is at GroovyUpdaterClassLoader :
public static GroovyUpdaterClassLoader createClassLoader() { return new GroovyUpdaterClassLoader(GroovyUpdaterClassLoader.class.getClassLoader(), createCompilerConfiguration()); } private static CompilerConfiguration createCompilerConfiguration() { final CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); compilerConfiguration.addCompilationCustomizers(createImportCustomizer(), createCompilationCustomizer()); return compilerConfiguration; }
to support custom compilation, we need support for the creation of custom compilation resources to be used.
How to Documentation
From 15.2.0 and 14.7.13 onward, it is possible to replace the default Compilation Customizers used by Bloomreach with custom Compilation Customizers. The custom Compilation Customizers can reuse Bloomreach configuration through some public static variables and methods in GroovyUpdaterClassLoader. Note that Bloomreach supports customizing the compilation customization used by Groovy but we do not support the customizations made by customers themselves: it is the customer's own responsibility that her customizers does not open up vulnerabilities wrt invocations which should not be allowed from the Groovy Updater. When making use of the below shown CompilationCustomizerFactory, the Compilation Customizers from Bloomreach are not used any more.
How to customize
In your project, below /cms/src/main/resources/META-INF add the file spring.factories [1] containing
org.springframework.boot.autoconfigure.EnableAutoConfiguration = org.myproject.spring.MyAppConfiguration
At /cms/src/main/java/org/myproject/spring add MyAppConfiguration containing for example:
package org.myproject.spring; import org.myproject.groovy.CompilationCustomizerFactoryImpl; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AppConfiguration { @Bean(initMethod = "init", destroyMethod = "destroy") public CompilationCustomizerFactoryImpl getCompilationCustomizerFactory() { return new CompilationCustomizerFactoryImpl(); } }
And at /cms/src/main/java/org/myproject/groovy add CompilationCustomizerFactoryImpl like:
package org.myproject.groovy; import org.codehaus.groovy.control.customizers.CompilationCustomizer; import org.onehippo.cms7.services.HippoServiceRegistry; import org.onehippo.repository.update.CompilationCustomizerFactory; public class CompilationCustomizerFactoryImpl implements CompilationCustomizerFactory { public void init() { HippoServiceRegistry.register(this, CompilationCustomizerFactory.class); } public void destroy() { HippoServiceRegistry.unregister(this, CompilationCustomizerFactory.class); } @Override public CompilationCustomizer[] createCompilationCustomizers() { // TODO return your custom compilation customers } }
Customization Example
An example of how the customization could look is as follows:
package org.myproject.groovy; import org.codehaus.groovy.control.customizers.CompilationCustomizer; import org.codehaus.groovy.control.customizers.SecureASTCustomizer; import org.onehippo.cms7.services.HippoServiceRegistry; import org.onehippo.repository.update.CompilationCustomizerFactory; import org.onehippo.repository.update.GroovyUpdaterClassLoader; import static org.onehippo.repository.update.GroovyUpdaterClassLoader.defaultImportsBlocklist; import static org.onehippo.repository.update.GroovyUpdaterClassLoader.defaultStarImportsBlocklist; public class CompilationCustomizerFactoryImpl implements CompilationCustomizerFactory { public void init() { HippoServiceRegistry.register(this, CompilationCustomizerFactory.class); } public void destroy() { HippoServiceRegistry.unregister(this, CompilationCustomizerFactory.class); } @Override public CompilationCustomizer[] createCompilationCustomizers() { final SecureASTCustomizer compilationCustomizer = new SecureASTCustomizer(); compilationCustomizer.setImportsWhitelist(myImportWhiteList); compilationCustomizer.setIndirectImportCheckEnabled(true); compilationCustomizer.addExpressionCheckers(new GroovyUpdaterClassLoader.DefaultUpdaterExpressionChecker()); return new CompilationCustomizer[] {GroovyUpdaterClassLoader.createDefaultImportCustomizer(), compilationCustomizer}; } }
where the above works with 'allow listing' classes instead of the default Bloomreach Compilation Customizer using 'disallow listing'
Attachments
Issue Links
- relates to
-
CMS-14612 [PaaS] Integrate Spring boot into CMS app
- Closed