mirror of
https://github.com/apache/struts.git
synced 2026-08-07 07:37:20 +00:00
WW-5440 Fix OGNL allowlist compat with Convention plugin
This commit is contained in:
+9
-2
@@ -36,7 +36,7 @@ import org.apache.struts2.dispatcher.DispatcherListener;
|
||||
* </p>
|
||||
*/
|
||||
public class ClasspathConfigurationProvider implements ConfigurationProvider, DispatcherListener {
|
||||
private ActionConfigBuilder actionConfigBuilder;
|
||||
private final ActionConfigBuilder actionConfigBuilder;
|
||||
private boolean devMode;
|
||||
private boolean reload;
|
||||
private boolean listeningToDispatcher;
|
||||
@@ -59,6 +59,7 @@ public class ClasspathConfigurationProvider implements ConfigurationProvider, Di
|
||||
/**
|
||||
* Not used.
|
||||
*/
|
||||
@Override
|
||||
public void destroy() {
|
||||
if (this.listeningToDispatcher) {
|
||||
Dispatcher.removeDispatcherListener(this);
|
||||
@@ -71,6 +72,7 @@ public class ClasspathConfigurationProvider implements ConfigurationProvider, Di
|
||||
*
|
||||
* @param configuration configuration
|
||||
*/
|
||||
@Override
|
||||
public void init(Configuration configuration) {
|
||||
if (devMode && reload && !listeningToDispatcher) {
|
||||
//this is the only way I found to be able to get added to to ConfigurationProvider list
|
||||
@@ -88,6 +90,7 @@ public class ClasspathConfigurationProvider implements ConfigurationProvider, Di
|
||||
*
|
||||
* @throws ConfigurationException in case of configuration errors
|
||||
*/
|
||||
@Override
|
||||
public void register(ContainerBuilder containerBuilder, LocatableProperties locatableProperties)
|
||||
throws ConfigurationException {
|
||||
}
|
||||
@@ -97,20 +100,24 @@ public class ClasspathConfigurationProvider implements ConfigurationProvider, Di
|
||||
*
|
||||
* @throws ConfigurationException in case of configuration errors
|
||||
*/
|
||||
@Override
|
||||
public void loadPackages() throws ConfigurationException {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if devMode, reload and actionConfigBuilder.needsReload()
|
||||
*/
|
||||
@Override
|
||||
public boolean needsReload() {
|
||||
return devMode && reload && actionConfigBuilder.needsReload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatcherInitialized(Dispatcher du) {
|
||||
du.getConfigurationManager().addContainerProvider(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatcherDestroyed(Dispatcher du) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-4
@@ -18,11 +18,11 @@
|
||||
*/
|
||||
package org.apache.struts2.convention;
|
||||
|
||||
import com.opensymphony.xwork2.config.PackageProvider;
|
||||
import com.opensymphony.xwork2.config.Configuration;
|
||||
import com.opensymphony.xwork2.config.ConfigurationException;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.config.PackageProvider;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -34,20 +34,23 @@ import com.opensymphony.xwork2.inject.Container;
|
||||
* </p>
|
||||
*/
|
||||
public class ClasspathPackageProvider implements PackageProvider {
|
||||
private ActionConfigBuilder actionConfigBuilder;
|
||||
private final ActionConfigBuilder actionConfigBuilder;
|
||||
|
||||
@Inject
|
||||
public ClasspathPackageProvider(Container container) {
|
||||
this.actionConfigBuilder = container.getInstance(ActionConfigBuilder.class, container.getInstance(String.class, ConventionConstants.CONVENTION_ACTION_CONFIG_BUILDER));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Configuration configuration) throws ConfigurationException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsReload() {
|
||||
return actionConfigBuilder.needsReload();
|
||||
return actionConfigBuilder.needsReload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadPackages() throws ConfigurationException {
|
||||
actionConfigBuilder.buildActionConfigs();
|
||||
}
|
||||
|
||||
+43
-22
@@ -24,6 +24,7 @@ import com.opensymphony.xwork2.FileManagerFactory;
|
||||
import com.opensymphony.xwork2.ObjectFactory;
|
||||
import com.opensymphony.xwork2.config.Configuration;
|
||||
import com.opensymphony.xwork2.config.ConfigurationException;
|
||||
import com.opensymphony.xwork2.config.ConfigurationUtil;
|
||||
import com.opensymphony.xwork2.config.entities.ActionConfig;
|
||||
import com.opensymphony.xwork2.config.entities.ExceptionMappingConfig;
|
||||
import com.opensymphony.xwork2.config.entities.InterceptorMapping;
|
||||
@@ -57,6 +58,7 @@ import org.apache.struts2.convention.annotation.ExceptionMappings;
|
||||
import org.apache.struts2.convention.annotation.Namespace;
|
||||
import org.apache.struts2.convention.annotation.Namespaces;
|
||||
import org.apache.struts2.convention.annotation.ParentPackage;
|
||||
import org.apache.struts2.ognl.ProviderAllowlist;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -125,6 +127,9 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
|
||||
private FileManager fileManager;
|
||||
private ClassFinderFactory classFinderFactory;
|
||||
|
||||
private final Set<Class<?>> allowlistClasses = new HashSet<>();
|
||||
private ProviderAllowlist providerAllowlist;
|
||||
|
||||
/**
|
||||
* Constructs actions based on a list of packages.
|
||||
*
|
||||
@@ -167,6 +172,11 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
|
||||
this.devMode = BooleanUtils.toBoolean(mode);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setProviderAllowlist(ProviderAllowlist providerAllowlist) {
|
||||
this.providerAllowlist = providerAllowlist;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param reload Reload configuration when classes change. Defaults to "false" and should not be used
|
||||
* in production.
|
||||
@@ -345,33 +355,38 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
|
||||
* annotation which is used to control the parent package for a specific action. Lastly, the
|
||||
* {@link ResultMapBuilder} is used to create ResultConfig instances of the action.
|
||||
*/
|
||||
@Override
|
||||
public void buildActionConfigs() {
|
||||
allowlistClasses.clear();
|
||||
|
||||
//setup reload class loader based on dev settings
|
||||
initReloadClassLoader();
|
||||
|
||||
if (!disableActionScanning) {
|
||||
if (actionPackages == null && packageLocators == null) {
|
||||
throw new ConfigurationException("At least a list of action packages or action package locators " +
|
||||
"must be given using one of the properties [struts.convention.action.packages] or " +
|
||||
"[struts.convention.package.locators]");
|
||||
}
|
||||
|
||||
if (LOG.isTraceEnabled()) {
|
||||
LOG.trace("Loading action configurations");
|
||||
if (actionPackages != null) {
|
||||
LOG.trace("Actions being loaded from action packages: {}", (Object[]) actionPackages);
|
||||
}
|
||||
if (packageLocators != null) {
|
||||
LOG.trace("Actions being loaded using package locator's: {}", (Object[]) packageLocators);
|
||||
}
|
||||
if (excludePackages != null) {
|
||||
LOG.trace("Excluding actions from packages: {}", (Object[]) excludePackages);
|
||||
}
|
||||
}
|
||||
|
||||
Set<Class<?>> classes = findActions();
|
||||
buildConfiguration(classes);
|
||||
if (disableActionScanning) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (actionPackages == null && packageLocators == null) {
|
||||
throw new ConfigurationException("At least a list of action packages or action package locators " +
|
||||
"must be given using one of the properties [struts.convention.action.packages] or " +
|
||||
"[struts.convention.package.locators]");
|
||||
}
|
||||
|
||||
if (LOG.isTraceEnabled()) {
|
||||
LOG.trace("Loading action configurations");
|
||||
if (actionPackages != null) {
|
||||
LOG.trace("Actions being loaded from action packages: {}", (Object[]) actionPackages);
|
||||
}
|
||||
if (packageLocators != null) {
|
||||
LOG.trace("Actions being loaded using package locator's: {}", (Object[]) packageLocators);
|
||||
}
|
||||
if (excludePackages != null) {
|
||||
LOG.trace("Excluding actions from packages: {}", (Object[]) excludePackages);
|
||||
}
|
||||
}
|
||||
|
||||
Set<Class<?>> classes = findActions();
|
||||
buildConfiguration(classes);
|
||||
}
|
||||
|
||||
protected ClassLoaderInterface getClassLoaderInterface() {
|
||||
@@ -765,7 +780,10 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
|
||||
} else if (actionAnnotation != null)
|
||||
createActionConfig(defaultPackageConfig, actionClass, defaultActionName, methodName, actionAnnotation, allowedMethods);
|
||||
}
|
||||
|
||||
allowlistClasses.addAll(ConfigurationUtil.getAllClassTypes(actionClass));
|
||||
}
|
||||
providerAllowlist.registerAllowlist(this, allowlistClasses);
|
||||
|
||||
buildIndexActions(packageConfigs);
|
||||
|
||||
@@ -1153,10 +1171,13 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
loadedFileUrls.clear();
|
||||
providerAllowlist.clearAllowlist(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsReload() {
|
||||
if (devMode && reload) {
|
||||
for (String url : loadedFileUrls) {
|
||||
|
||||
+45
-7
@@ -18,9 +18,21 @@
|
||||
*/
|
||||
package org.apache.struts2.convention;
|
||||
|
||||
import com.opensymphony.xwork2.*;
|
||||
import com.opensymphony.xwork2.ActionChainResult;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.FileManager;
|
||||
import com.opensymphony.xwork2.FileManagerFactory;
|
||||
import com.opensymphony.xwork2.ObjectFactory;
|
||||
import com.opensymphony.xwork2.Result;
|
||||
import com.opensymphony.xwork2.config.Configuration;
|
||||
import com.opensymphony.xwork2.config.entities.*;
|
||||
import com.opensymphony.xwork2.config.entities.ActionConfig;
|
||||
import com.opensymphony.xwork2.config.entities.ExceptionMappingConfig;
|
||||
import com.opensymphony.xwork2.config.entities.InterceptorConfig;
|
||||
import com.opensymphony.xwork2.config.entities.InterceptorMapping;
|
||||
import com.opensymphony.xwork2.config.entities.InterceptorStackConfig;
|
||||
import com.opensymphony.xwork2.config.entities.PackageConfig;
|
||||
import com.opensymphony.xwork2.config.entities.ResultConfig;
|
||||
import com.opensymphony.xwork2.config.entities.ResultTypeConfig;
|
||||
import com.opensymphony.xwork2.config.impl.DefaultConfiguration;
|
||||
import com.opensymphony.xwork2.factory.DefaultInterceptorFactory;
|
||||
import com.opensymphony.xwork2.factory.DefaultResultFactory;
|
||||
@@ -32,12 +44,20 @@ import com.opensymphony.xwork2.util.fs.DefaultFileManager;
|
||||
import com.opensymphony.xwork2.util.fs.DefaultFileManagerFactory;
|
||||
import com.opensymphony.xwork2.util.reflection.ReflectionException;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.struts2.convention.actions.DefaultResultPathAction;
|
||||
import org.apache.struts2.convention.actions.NoAnnotationAction;
|
||||
import org.apache.struts2.convention.actions.Skip;
|
||||
import org.apache.struts2.convention.actions.action.*;
|
||||
import org.apache.struts2.convention.actions.action.ActionNameAction;
|
||||
import org.apache.struts2.convention.actions.action.ActionNamesAction;
|
||||
import org.apache.struts2.convention.actions.action.ClassLevelAnnotationAction;
|
||||
import org.apache.struts2.convention.actions.action.ClassLevelAnnotationDefaultMethodAction;
|
||||
import org.apache.struts2.convention.actions.action.ClassLevelAnnotationsAction;
|
||||
import org.apache.struts2.convention.actions.action.ClassLevelAnnotationsDefaultMethodAction;
|
||||
import org.apache.struts2.convention.actions.action.ClassNameAction;
|
||||
import org.apache.struts2.convention.actions.action.SingleActionNameAction;
|
||||
import org.apache.struts2.convention.actions.action.TestAction;
|
||||
import org.apache.struts2.convention.actions.action.TestExtends;
|
||||
import org.apache.struts2.convention.actions.allowedmethods.ClassLevelAllowedMethodsAction;
|
||||
import org.apache.struts2.convention.actions.allowedmethods.PackageLevelAllowedMethodsAction;
|
||||
import org.apache.struts2.convention.actions.allowedmethods.sub.PackageLevelAllowedMethodsChildAction;
|
||||
@@ -61,7 +81,15 @@ import org.apache.struts2.convention.actions.parentpackage.ClassLevelParentPacka
|
||||
import org.apache.struts2.convention.actions.parentpackage.PackageLevelParentPackageAction;
|
||||
import org.apache.struts2.convention.actions.parentpackage.sub.ClassLevelParentPackageChildAction;
|
||||
import org.apache.struts2.convention.actions.parentpackage.sub.PackageLevelParentPackageChildAction;
|
||||
import org.apache.struts2.convention.actions.result.*;
|
||||
import org.apache.struts2.convention.actions.result.ActionLevelResultAction;
|
||||
import org.apache.struts2.convention.actions.result.ActionLevelResultsAction;
|
||||
import org.apache.struts2.convention.actions.result.ActionLevelResultsNamesAction;
|
||||
import org.apache.struts2.convention.actions.result.ClassLevelResultAction;
|
||||
import org.apache.struts2.convention.actions.result.ClassLevelResultsAction;
|
||||
import org.apache.struts2.convention.actions.result.GlobalResultAction;
|
||||
import org.apache.struts2.convention.actions.result.GlobalResultOverrideAction;
|
||||
import org.apache.struts2.convention.actions.result.InheritedResultExtends;
|
||||
import org.apache.struts2.convention.actions.result.OverrideResultAction;
|
||||
import org.apache.struts2.convention.actions.resultpath.ClassLevelResultPathAction;
|
||||
import org.apache.struts2.convention.actions.resultpath.PackageLevelResultPathAction;
|
||||
import org.apache.struts2.convention.actions.skip.Index;
|
||||
@@ -69,15 +97,24 @@ import org.apache.struts2.convention.actions.transactions.TransNameAction;
|
||||
import org.apache.struts2.convention.annotation.Action;
|
||||
import org.apache.struts2.convention.annotation.Actions;
|
||||
import org.apache.struts2.convention.dontfind.DontFindMeAction;
|
||||
import org.apache.struts2.ognl.ProviderAllowlist;
|
||||
import org.apache.struts2.result.ServletDispatcherResult;
|
||||
import org.easymock.EasyMock;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.apache.struts2.convention.ReflectionTools.getAnnotation;
|
||||
import static org.easymock.EasyMock.*;
|
||||
import static org.easymock.EasyMock.checkOrder;
|
||||
import static org.easymock.EasyMock.createStrictMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -388,6 +425,7 @@ public class PackageBasedActionConfigBuilderTest extends TestCase {
|
||||
fileManagerFactory.setFileManager(new DefaultFileManager());
|
||||
builder.setFileManagerFactory(fileManagerFactory);
|
||||
builder.setPackageLocatorsBase("org.apache.struts2.convention.actions");
|
||||
builder.setProviderAllowlist(new ProviderAllowlist());
|
||||
builder.buildActionConfigs();
|
||||
verify(resultMapBuilder);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user