mirror of
https://github.com/apache/struts.git
synced 2026-08-08 08:07:17 +00:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f0b3a1d213 | |||
| 2306f5f7fa | |||
| ed7f9dd4cb | |||
| cf53b59647 | |||
| 6dd6e5cfb7 | |||
| b9a0c497d3 | |||
| 2f95b9a130 | |||
| 103e3b174e | |||
| 2776b34b44 | |||
| 287e3bc8cb | |||
| 677ccebe83 | |||
| f11ac901d3 | |||
| 3fddfb6eb5 | |||
| 744c1f409d | |||
| 54a4dce7bf | |||
| 16eb7fa768 | |||
| 631ce98d17 | |||
| 086b637355 | |||
| ae56301979 | |||
| 73da12e723 | |||
| 583da3d5df | |||
| 9e8627ca66 | |||
| c349dfa5ab | |||
| 4d888a5ab6 | |||
| 1ed29d508f | |||
| 3523064939 | |||
| 54dff362f5 | |||
| b12864dd38 |
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-blank</artifactId>
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.apache.struts2.interceptor.validation.SkipValidation;
|
||||
|
||||
public class Login extends ExampleSupport {
|
||||
|
||||
@Override
|
||||
public String execute() throws Exception {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-jboss-blank</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-mailreader</artifactId>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-portlet</artifactId>
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-rest-showcase</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
<name>Struts 2 Rest Showcase Webapp</name>
|
||||
<description>Struts 2 Rest Showcase Example</description>
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-showcase</artifactId>
|
||||
|
||||
+2
-1
@@ -36,7 +36,8 @@ public class SaveGangsterAction extends Action {
|
||||
// Some code to save the gangster to the db as necessary
|
||||
GangsterForm gform = (GangsterForm) form;
|
||||
ActionMessages messages = new ActionMessages();
|
||||
messages.add("msg", new ActionMessage("Gangster " + gform.getName() + " added successfully"));
|
||||
System.out.println(gform.getName());
|
||||
messages.add("msg", new ActionMessage("struts1.gangsterAdded", gform.getName()));
|
||||
addMessages(request, messages);
|
||||
|
||||
return mapping.findForward("success");
|
||||
|
||||
@@ -7,3 +7,5 @@ item.create=Create {0}
|
||||
item.list={0} List
|
||||
|
||||
token.transfer.time=The bank transfer was executed at {0,date,HH:mm:ss MM-dd-yyyy}
|
||||
|
||||
struts1.gangsterAdded=Gangster {0} added successfully
|
||||
@@ -5,3 +5,5 @@ item.create={0} neu anlegen
|
||||
item.list={0}-Liste
|
||||
|
||||
token.transfer.time=Die \u00dcberweisung wurde am {0,date,HH:mm:ss MM-dd-yyyy} durchgef\u00fchrt
|
||||
|
||||
struts1.gangsterAdded=Gangster {0} wurde erfolgreich hinzugefugt
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
struts1.gangsterAdded=Gangster {0} anadido con exito
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-assembly</artifactId>
|
||||
|
||||
+3
-3
@@ -10,7 +10,7 @@
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-bom</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Struts 2 Bill of Materials</name>
|
||||
@@ -25,7 +25,7 @@
|
||||
</licenses>
|
||||
|
||||
<properties>
|
||||
<struts-version.version>2.3.31</struts-version.version>
|
||||
<struts-version.version>2.3.34</struts-version.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
@@ -197,6 +197,6 @@
|
||||
</dependencyManagement>
|
||||
|
||||
<scm>
|
||||
<tag>STRUTS_2_3_31</tag>
|
||||
<tag>STRUTS_2_3_34</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-admin-bundle</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-demo-bundle</artifactId>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
<artifactId>struts2-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
+5
-1
@@ -120,7 +120,11 @@ public class JakartaMultiPartRequest implements MultiPartRequest {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Preparing error message for key: [#0]", errorKey);
|
||||
}
|
||||
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, e.getMessage(), args);
|
||||
if (LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null, new Object[0]) == null) {
|
||||
return LocalizedTextUtil.findText(this.getClass(), "struts.messages.error.uploading", defaultLocale, null, new Object[] { e.getMessage() });
|
||||
} else {
|
||||
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null, args);
|
||||
}
|
||||
}
|
||||
|
||||
protected void processUpload(HttpServletRequest request, String saveDir) throws FileUploadException, UnsupportedEncodingException {
|
||||
|
||||
+5
-1
@@ -539,7 +539,11 @@ public class JakartaStreamMultiPartRequest implements MultiPartRequest {
|
||||
String errorKey = "struts.message.upload.error." + e.getClass().getSimpleName();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Preparing error message for key: [#0]", errorKey);
|
||||
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, e.getMessage(), args);
|
||||
if (LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null, new Object[0]) == null) {
|
||||
return LocalizedTextUtil.findText(this.getClass(), "struts.messages.error.uploading", defaultLocale, null, new Object[] { e.getMessage() });
|
||||
} else {
|
||||
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+5
-1
@@ -108,7 +108,11 @@ public class MultiPartRequestWrapper extends StrutsRequestWrapper {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Preparing error message for key: [#0]", errorKey);
|
||||
}
|
||||
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, e.getMessage(), args);
|
||||
if (LocalizedTextUtil.findText(this.getClass(), errorKey, getLocale(), null, new Object[0]) == null) {
|
||||
return LocalizedTextUtil.findText(this.getClass(), "struts.messages.error.uploading", defaultLocale, null, new Object[] { e.getMessage() });
|
||||
} else {
|
||||
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,6 +34,7 @@ import freemarker.cache.FileTemplateLoader;
|
||||
import freemarker.cache.MultiTemplateLoader;
|
||||
import freemarker.cache.TemplateLoader;
|
||||
import freemarker.cache.WebappTemplateLoader;
|
||||
import freemarker.core.TemplateClassResolver;
|
||||
import freemarker.ext.jsp.TaglibFactory;
|
||||
import freemarker.ext.servlet.HttpRequestHashModel;
|
||||
import freemarker.ext.servlet.HttpRequestParametersHashModel;
|
||||
@@ -344,6 +345,9 @@ public class FreemarkerManager {
|
||||
configuration.setLocalizedLookup(false);
|
||||
configuration.setWhitespaceStripping(true);
|
||||
|
||||
LOG.debug("Sets NewBuiltinClassResolver to TemplateClassResolver.SAFER_RESOLVER");
|
||||
configuration.setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER);
|
||||
|
||||
return configuration;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-cdi-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-codebehind-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-config-browser-plugin</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-convention-plugin</artifactId>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<parent>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -33,7 +33,7 @@ dojo.global=function(){
|
||||
return dj_currentContext;
|
||||
};
|
||||
dojo.locale=djConfig.locale;
|
||||
dojo.version={major:0,minor:4,patch:3,flag:"",revision:Number("$Rev$".match(/[0-9]+/)[0]),toString:function(){
|
||||
dojo.version={major:0,minor:4,patch:3,flag:"",revision:Number("$Rev: 670371 $".match(/[0-9]+/)[0]),toString:function(){
|
||||
with(dojo.version){
|
||||
return major+"."+minor+"."+patch+flag+" ("+revision+")";
|
||||
}
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ dojo.locale = djConfig.locale;
|
||||
dojo.version = {
|
||||
// summary: version number of this instance of dojo.
|
||||
major: 0, minor: 4, patch: 3, flag: "",
|
||||
revision: Number("$Rev$".match(/[0-9]+/)[0]),
|
||||
revision: Number("$Rev: 670371 $".match(/[0-9]+/)[0]),
|
||||
toString: function(){
|
||||
with(dojo.version){
|
||||
return major + "." + minor + "." + patch + flag + " (" + revision + ")"; // String
|
||||
|
||||
+1
-1
@@ -90,7 +90,7 @@ dojo.locale = djConfig.locale;
|
||||
dojo.version = {
|
||||
// summary: version number of this instance of dojo.
|
||||
major: 0, minor: 4, patch: 3, flag: "",
|
||||
revision: Number("$Rev$".match(/[0-9]+/)[0]),
|
||||
revision: Number("$Rev: 670371 $".match(/[0-9]+/)[0]),
|
||||
toString: function(){
|
||||
with(dojo.version){
|
||||
return major + "." + minor + "." + patch + flag + " (" + revision + ")"; // String
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-dwr-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-embeddedjsp-plugin</artifactId>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-gxp-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-jasperreports-plugin</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-java8-support-plugin</artifactId>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-javatemplates-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-jfreechart-plugin</artifactId>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-jsf-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-json-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-junit-plugin</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-oval-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-pell-multipart-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-plexus-plugin</artifactId>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-portlet-tiles-plugin</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-portlet-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-rest-plugin</artifactId>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
package org.apache.struts2.rest;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import org.apache.struts2.rest.handler.ContentTypeHandler;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -58,10 +59,16 @@ public interface ContentTypeHandlerManager {
|
||||
* @param target The object to return, usually the action object
|
||||
* @return The new result code to process
|
||||
* @throws IOException If unable to write to the response
|
||||
*
|
||||
* @deprecated use version which requires {@link ActionInvocation}
|
||||
*/
|
||||
@Deprecated
|
||||
String handleResult(ActionConfig actionConfig, Object methodResult, Object target)
|
||||
throws IOException;
|
||||
|
||||
String handleResult(ActionInvocation actionInvocation, Object methodResult, Object target)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Finds the extension in the url
|
||||
*
|
||||
|
||||
@@ -61,7 +61,7 @@ public class ContentTypeInterceptor implements Interceptor {
|
||||
if (request.getContentLength() > 0) {
|
||||
InputStream is = request.getInputStream();
|
||||
InputStreamReader reader = new InputStreamReader(is);
|
||||
handler.toObject(reader, target);
|
||||
handler.toObject(invocation, reader, target);
|
||||
}
|
||||
return invocation.invoke();
|
||||
}
|
||||
|
||||
+16
-4
@@ -21,9 +21,12 @@
|
||||
|
||||
package org.apache.struts2.rest;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.config.entities.ActionConfig;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.rest.handler.ContentTypeHandler;
|
||||
|
||||
@@ -41,6 +44,8 @@ import java.util.Set;
|
||||
*/
|
||||
public class DefaultContentTypeHandlerManager implements ContentTypeHandlerManager {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DefaultContentTypeHandlerManager.class);
|
||||
|
||||
/** ContentTypeHandlers keyed by the extension */
|
||||
Map<String, ContentTypeHandler> handlersByExtension = new HashMap<String, ContentTypeHandler>();
|
||||
/** ContentTypeHandlers keyed by the content-type */
|
||||
@@ -115,7 +120,7 @@ public class DefaultContentTypeHandlerManager implements ContentTypeHandlerManag
|
||||
|
||||
/**
|
||||
* Gets the handler for the response by looking at the extension of the request
|
||||
* @param req The request
|
||||
* @param request The request
|
||||
* @return The appropriate handler
|
||||
*
|
||||
* WW-4588: modified to get a handler for the response side and auto generate the response type
|
||||
@@ -153,20 +158,27 @@ public class DefaultContentTypeHandlerManager implements ContentTypeHandlerManag
|
||||
return handler;
|
||||
}
|
||||
|
||||
public String handleResult(ActionConfig actionConfig, Object methodResult, Object target) throws IOException {
|
||||
LOG.warn("This method is deprecated!");
|
||||
return readResultCode(methodResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the result using handlers to generate content type-specific content
|
||||
*
|
||||
* @param actionConfig The action config for the current request
|
||||
* @param invocation The action invocation for the current request
|
||||
* @param methodResult The object returned from the action method
|
||||
* @param target The object to return, usually the action object
|
||||
* @return The new result code to process
|
||||
* @throws IOException If unable to write to the response
|
||||
*/
|
||||
public String handleResult(ActionConfig actionConfig, Object methodResult, Object target) throws IOException {
|
||||
public String handleResult(ActionInvocation invocation, Object methodResult, Object target) throws IOException {
|
||||
String resultCode = readResultCode(methodResult);
|
||||
Integer statusCode = readStatusCode(methodResult);
|
||||
HttpServletRequest req = ServletActionContext.getRequest();
|
||||
HttpServletResponse res = ServletActionContext.getResponse();
|
||||
ActionConfig actionConfig = invocation.getProxy().getConfig();
|
||||
|
||||
if(statusCode != null) {
|
||||
res.setStatus(statusCode);
|
||||
}
|
||||
@@ -178,7 +190,7 @@ public class DefaultContentTypeHandlerManager implements ContentTypeHandlerManag
|
||||
resultCode = extCode;
|
||||
} else {
|
||||
StringWriter writer = new StringWriter();
|
||||
resultCode = handler.fromObject(target, resultCode, writer);
|
||||
resultCode = handler.fromObject(invocation, target, resultCode, writer);
|
||||
String text = writer.toString();
|
||||
if (text.length() > 0) {
|
||||
byte[] data = text.getBytes("UTF-8");
|
||||
|
||||
@@ -229,9 +229,7 @@ public class RestActionInvocation extends DefaultActionInvocation {
|
||||
if (handler != null && !(handler instanceof HtmlHandler)) {
|
||||
|
||||
// Specific representation (json, xml...)
|
||||
resultCode = handlerSelector.handleResult(
|
||||
this.getProxy().getConfig(), httpHeaders, target);
|
||||
|
||||
resultCode = handlerSelector.handleResult(this, httpHeaders, target);
|
||||
} else {
|
||||
|
||||
// Normal struts execution (html o other struts result)
|
||||
|
||||
@@ -221,7 +221,7 @@ public class RestWorkflowInterceptor extends MethodFilterInterceptor {
|
||||
|
||||
errors.put("actionErrors", validationAwareAction.getActionErrors());
|
||||
errors.put("fieldErrors", validationAwareAction.getFieldErrors());
|
||||
return manager.handleResult(invocation.getProxy().getConfig(), info, errors);
|
||||
return manager.handleResult(invocation, info, errors);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.rest.handler;
|
||||
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
|
||||
abstract public class AbstractContentTypeHandler implements ContentTypeHandler {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractContentTypeHandler.class);
|
||||
|
||||
public void toObject(Reader in, Object target) throws IOException {
|
||||
LOG.warn("This method is deprecated!");
|
||||
}
|
||||
|
||||
public String fromObject(Object obj, String resultCode, Writer stream) throws IOException {
|
||||
LOG.warn("This method is deprecated!");
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.rest.handler;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface AllowedClassNames {
|
||||
Set<String> allowedClassNames();
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.rest.handler;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface AllowedClasses {
|
||||
Set<Class<?>> allowedClasses();
|
||||
}
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
@@ -34,9 +36,15 @@ public interface ContentTypeHandler {
|
||||
* Populates an object using data from the input stream
|
||||
* @param in The input stream, usually the body of the request
|
||||
* @param target The target, usually the action class
|
||||
* @throws IOException If unable to write to the output stream
|
||||
*
|
||||
* @deprecated use version which requires {@link ActionInvocation}
|
||||
*/
|
||||
@Deprecated
|
||||
void toObject(Reader in, Object target) throws IOException;
|
||||
|
||||
|
||||
void toObject(ActionInvocation invocation, Reader in, Object target) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes content to the stream
|
||||
*
|
||||
@@ -45,9 +53,14 @@ public interface ContentTypeHandler {
|
||||
* @param stream The output stream, usually the response
|
||||
* @return The new result code
|
||||
* @throws IOException If unable to write to the output stream
|
||||
*
|
||||
* @deprecated use version which requires {@link ActionInvocation}
|
||||
*/
|
||||
@Deprecated
|
||||
String fromObject(Object obj, String resultCode, Writer stream) throws IOException;
|
||||
|
||||
|
||||
String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer stream) throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the content type for this handler
|
||||
*
|
||||
|
||||
+12
-6
@@ -20,6 +20,8 @@
|
||||
*/
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
@@ -34,21 +36,25 @@ import java.io.Reader;
|
||||
* {@link http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4}
|
||||
*
|
||||
*/
|
||||
public class FormUrlEncodedHandler implements ContentTypeHandler {
|
||||
public class FormUrlEncodedHandler extends AbstractContentTypeHandler {
|
||||
|
||||
public static final String CONTENT_TYPE = "application/x-www-form-urlencoded";
|
||||
|
||||
public String fromObject(Object obj, String resultCode, Writer out) throws IOException {
|
||||
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer out) throws IOException {
|
||||
throw new IOException("Conversion from Object to '"+getContentType()+"' is not supported");
|
||||
}
|
||||
|
||||
/** No transformation is required as the framework handles this data */
|
||||
public void toObject(Reader in, Object target) {
|
||||
/**
|
||||
* No transformation is required as the framework handles this data
|
||||
*
|
||||
* @param in The input stream, usually the body of the request
|
||||
* @param target The target, usually the action class
|
||||
*/
|
||||
public void toObject(ActionInvocation invocation, Reader in, Object target) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension is not used by this handler
|
||||
* @return
|
||||
* @return The extension is not used by this handler
|
||||
*/
|
||||
public String getExtension() {
|
||||
return null;
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
@@ -28,13 +30,13 @@ import java.io.Writer;
|
||||
/**
|
||||
* Handles HTML content, usually just a simple passthrough to the framework
|
||||
*/
|
||||
public class HtmlHandler implements ContentTypeHandler {
|
||||
public class HtmlHandler extends AbstractContentTypeHandler {
|
||||
|
||||
public String fromObject(Object obj, String resultCode, Writer out) throws IOException {
|
||||
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer out) throws IOException {
|
||||
return resultCode;
|
||||
}
|
||||
|
||||
public void toObject(Reader in, Object target) {
|
||||
public void toObject(ActionInvocation invocation, Reader in, Object target) {
|
||||
}
|
||||
|
||||
public String getExtension() {
|
||||
|
||||
@@ -21,11 +21,12 @@
|
||||
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.codehaus.jackson.map.ObjectReader;
|
||||
import org.codehaus.jackson.map.SerializationConfig.Feature;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
@@ -34,20 +35,19 @@ import java.io.Writer;
|
||||
/**
|
||||
* Handles JSON content using jackson-lib
|
||||
*/
|
||||
public class JacksonLibHandler implements ContentTypeHandler {
|
||||
public class JacksonLibHandler extends AbstractContentTypeHandler {
|
||||
|
||||
private static final String DEFAULT_CONTENT_TYPE = "application/json";
|
||||
private String defaultEncoding = "ISO-8859-1";
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
public void toObject(Reader in, Object target) throws IOException {
|
||||
|
||||
public void toObject(ActionInvocation invocation, Reader in, Object target) throws IOException {
|
||||
mapper.configure(Feature.WRITE_NULL_MAP_VALUES, false);
|
||||
ObjectReader or = mapper.readerForUpdating(target);
|
||||
or.readValue(in); //, new TypeReference<clazz>);
|
||||
or.readValue(in);
|
||||
}
|
||||
|
||||
public String fromObject(Object obj, String resultCode, Writer stream) throws IOException {
|
||||
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer stream) throws IOException {
|
||||
mapper.configure(Feature.WRITE_NULL_MAP_VALUES, false);
|
||||
mapper.writeValue(stream, obj);
|
||||
return null;
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import net.sf.json.JSONArray;
|
||||
import net.sf.json.JSONObject;
|
||||
import net.sf.json.JsonConfig;
|
||||
@@ -37,12 +38,12 @@ import com.opensymphony.xwork2.inject.Inject;
|
||||
/**
|
||||
* Handles JSON content using json-lib
|
||||
*/
|
||||
public class JsonLibHandler implements ContentTypeHandler {
|
||||
public class JsonLibHandler extends AbstractContentTypeHandler {
|
||||
|
||||
private static final String DEFAULT_CONTENT_TYPE = "application/json";
|
||||
private String defaultEncoding = "ISO-8859-1";
|
||||
|
||||
public void toObject(Reader in, Object target) throws IOException {
|
||||
public void toObject(ActionInvocation invocation, Reader in, Object target) throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
char[] buffer = new char[1024];
|
||||
int len = 0;
|
||||
@@ -63,7 +64,7 @@ public class JsonLibHandler implements ContentTypeHandler {
|
||||
}
|
||||
}
|
||||
|
||||
public String fromObject(Object obj, String resultCode, Writer stream) throws IOException {
|
||||
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer stream) throws IOException {
|
||||
if (obj != null) {
|
||||
if (isArray(obj)) {
|
||||
JSONArray jsonArray = JSONArray.fromObject(obj);
|
||||
|
||||
+12
-6
@@ -20,6 +20,8 @@
|
||||
*/
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
@@ -35,21 +37,25 @@ import java.io.Reader;
|
||||
* {@link http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4}
|
||||
*
|
||||
*/
|
||||
public class MultipartFormDataHandler implements ContentTypeHandler {
|
||||
public class MultipartFormDataHandler extends AbstractContentTypeHandler {
|
||||
|
||||
public static final String CONTENT_TYPE = "multipart/form-data";
|
||||
|
||||
public String fromObject(Object obj, String resultCode, Writer out) throws IOException {
|
||||
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer out) throws IOException {
|
||||
throw new IOException("Conversion from Object to '"+getContentType()+"' is not supported");
|
||||
}
|
||||
|
||||
/** No transformation is required as the framework handles this data */
|
||||
public void toObject(Reader in, Object target) {
|
||||
/**
|
||||
* No transformation is required as the framework handles this data
|
||||
*
|
||||
* @param in The input stream, usually the body of the request
|
||||
* @param target The target, usually the action class
|
||||
*/
|
||||
public void toObject(ActionInvocation invocation, Reader in, Object target) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension is not used by this handler
|
||||
* @return
|
||||
* @return The extension is not used by this handler
|
||||
*/
|
||||
public String getExtension() {
|
||||
return null;
|
||||
|
||||
@@ -21,34 +21,98 @@
|
||||
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.ModelDriven;
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.security.ArrayTypePermission;
|
||||
import com.thoughtworks.xstream.security.ExplicitTypePermission;
|
||||
import com.thoughtworks.xstream.security.NoTypePermission;
|
||||
import com.thoughtworks.xstream.security.NullPermission;
|
||||
import com.thoughtworks.xstream.security.PrimitiveTypePermission;
|
||||
import com.thoughtworks.xstream.security.TypePermission;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Handles XML content
|
||||
*/
|
||||
public class XStreamHandler implements ContentTypeHandler {
|
||||
public class XStreamHandler extends AbstractContentTypeHandler {
|
||||
|
||||
public String fromObject(Object obj, String resultCode, Writer out) throws IOException {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(XStreamHandler.class);
|
||||
|
||||
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer out) throws IOException {
|
||||
if (obj != null) {
|
||||
XStream xstream = createXStream();
|
||||
XStream xstream = createXStream(invocation);
|
||||
xstream.toXML(obj, out);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void toObject(Reader in, Object target) {
|
||||
XStream xstream = createXStream();
|
||||
public void toObject(ActionInvocation invocation, Reader in, Object target) {
|
||||
XStream xstream = createXStream(invocation);
|
||||
xstream.fromXML(in, target);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated use version with {@link ActionInvocation}
|
||||
*/
|
||||
@Deprecated
|
||||
protected XStream createXStream() {
|
||||
LOG.warn("You are using a deprecated API!");
|
||||
return new XStream();
|
||||
}
|
||||
|
||||
protected XStream createXStream(ActionInvocation invocation) {
|
||||
XStream stream = new XStream();
|
||||
LOG.debug("Clears existing permissions");
|
||||
stream.addPermission(NoTypePermission.NONE);
|
||||
|
||||
LOG.debug("Adds per action permissions");
|
||||
addPerActionPermission(invocation, stream);
|
||||
|
||||
LOG.debug("Adds default permissions");
|
||||
addDefaultPermissions(invocation, stream);
|
||||
return stream;
|
||||
}
|
||||
|
||||
private void addPerActionPermission(ActionInvocation invocation, XStream stream) {
|
||||
Object action = invocation.getAction();
|
||||
if (action instanceof AllowedClasses) {
|
||||
Set<Class<?>> allowedClasses = ((AllowedClasses) action).allowedClasses();
|
||||
stream.addPermission(new ExplicitTypePermission(allowedClasses.toArray(new Class[allowedClasses.size()])));
|
||||
}
|
||||
if (action instanceof AllowedClassNames) {
|
||||
Set<String> allowedClassNames = ((AllowedClassNames) action).allowedClassNames();
|
||||
stream.addPermission(new ExplicitTypePermission(allowedClassNames.toArray(new String[allowedClassNames.size()])));
|
||||
}
|
||||
if (action instanceof XStreamPermissionProvider) {
|
||||
Collection<TypePermission> permissions = ((XStreamPermissionProvider) action).getTypePermissions();
|
||||
for (TypePermission permission : permissions) {
|
||||
stream.addPermission(permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void addDefaultPermissions(ActionInvocation invocation, XStream stream) {
|
||||
stream.addPermission(new ExplicitTypePermission(new Class[]{invocation.getAction().getClass()}));
|
||||
if (invocation.getAction() instanceof ModelDriven) {
|
||||
stream.addPermission(new ExplicitTypePermission(new Class[]{((ModelDriven) invocation.getAction()).getModel().getClass()}));
|
||||
}
|
||||
stream.addPermission(NullPermission.NULL);
|
||||
stream.addPermission(PrimitiveTypePermission.PRIMITIVES);
|
||||
stream.addPermission(ArrayTypePermission.ARRAYS);
|
||||
stream.addPermission(CollectionTypePermission.COLLECTIONS);
|
||||
stream.addPermission(new ExplicitTypePermission(new Class[]{Date.class}));
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return "application/xml";
|
||||
}
|
||||
@@ -56,4 +120,15 @@ public class XStreamHandler implements ContentTypeHandler {
|
||||
public String getExtension() {
|
||||
return "xml";
|
||||
}
|
||||
|
||||
private static class CollectionTypePermission implements TypePermission {
|
||||
|
||||
private static final TypePermission COLLECTIONS = new CollectionTypePermission();
|
||||
|
||||
public boolean allows(Class type) {
|
||||
return type != null && type.isInterface() &&
|
||||
(Collection.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.struts2.rest.handler;
|
||||
|
||||
import com.thoughtworks.xstream.security.TypePermission;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface XStreamPermissionProvider {
|
||||
Collection<TypePermission> getTypePermissions();
|
||||
}
|
||||
+17
-5
@@ -24,10 +24,14 @@ package org.apache.struts2.rest;
|
||||
import com.mockobjects.dynamic.C;
|
||||
import com.mockobjects.dynamic.Mock;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.config.entities.ActionConfig;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.mock.MockActionInvocation;
|
||||
import com.opensymphony.xwork2.mock.MockActionProxy;
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.rest.handler.AbstractContentTypeHandler;
|
||||
import org.apache.struts2.rest.handler.ContentTypeHandler;
|
||||
import org.apache.struts2.rest.handler.FormUrlEncodedHandler;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
@@ -49,6 +53,7 @@ public class ContentTypeHandlerManagerTest extends TestCase {
|
||||
private DefaultContentTypeHandlerManager mgr;
|
||||
private MockHttpServletResponse mockResponse;
|
||||
private MockHttpServletRequest mockRequest;
|
||||
private MockActionInvocation invocation;
|
||||
|
||||
@Override
|
||||
public void setUp() {
|
||||
@@ -59,6 +64,9 @@ public class ContentTypeHandlerManagerTest extends TestCase {
|
||||
ActionContext.setContext(new ActionContext(new HashMap()));
|
||||
ServletActionContext.setRequest(mockRequest);
|
||||
ServletActionContext.setResponse(mockResponse);
|
||||
|
||||
invocation = new MockActionInvocation();
|
||||
invocation.setProxy(new MockActionProxy());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,9 +79,9 @@ public class ContentTypeHandlerManagerTest extends TestCase {
|
||||
public void testHandleResultOK() throws IOException {
|
||||
|
||||
String obj = "mystring";
|
||||
ContentTypeHandler handler = new ContentTypeHandler() {
|
||||
public void toObject(Reader in, Object target) {}
|
||||
public String fromObject(Object obj, String resultCode, Writer stream) throws IOException {
|
||||
ContentTypeHandler handler = new AbstractContentTypeHandler() {
|
||||
public void toObject(ActionInvocation invocation, Reader in, Object target) {}
|
||||
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer stream) throws IOException {
|
||||
stream.write(obj.toString());
|
||||
return resultCode;
|
||||
}
|
||||
@@ -82,7 +90,11 @@ public class ContentTypeHandlerManagerTest extends TestCase {
|
||||
};
|
||||
mgr.handlersByExtension.put("xml", handler);
|
||||
mgr.setDefaultExtension("xml");
|
||||
mgr.handleResult(new ActionConfig.Builder("", "", "").build(), new DefaultHttpHeaders().withStatus(SC_OK), obj);
|
||||
ActionConfig actionConfig = new ActionConfig.Builder("", "", "").build();
|
||||
MockActionProxy proxy = new MockActionProxy();
|
||||
proxy.setConfig(actionConfig);
|
||||
invocation.setProxy(proxy);
|
||||
mgr.handleResult(invocation, new DefaultHttpHeaders().withStatus(SC_OK), obj);
|
||||
|
||||
assertEquals(obj.getBytes().length, mockResponse.getContentLength());
|
||||
}
|
||||
@@ -92,7 +104,7 @@ public class ContentTypeHandlerManagerTest extends TestCase {
|
||||
Mock mockHandlerXml = new Mock(ContentTypeHandler.class);
|
||||
mockHandlerXml.matchAndReturn("getExtension", "xml");
|
||||
mgr.handlersByExtension.put("xml", (ContentTypeHandler) mockHandlerXml.proxy());
|
||||
mgr.handleResult(null, new DefaultHttpHeaders().withStatus(SC_NOT_MODIFIED), new Object());
|
||||
mgr.handleResult(invocation, new DefaultHttpHeaders().withStatus(SC_NOT_MODIFIED), new Object());
|
||||
|
||||
assertEquals(0, mockResponse.getContentLength());
|
||||
}
|
||||
|
||||
+5
-3
@@ -1,8 +1,10 @@
|
||||
package org.apache.struts2.rest;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.XWorkTestCase;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Scope;
|
||||
import org.apache.struts2.rest.handler.AbstractContentTypeHandler;
|
||||
import org.apache.struts2.rest.handler.ContentTypeHandler;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
@@ -113,13 +115,13 @@ class DummyContainer implements Container {
|
||||
private ContentTypeHandler handler;
|
||||
|
||||
DummyContainer(final String contentType, final String extension) {
|
||||
handler = new ContentTypeHandler() {
|
||||
handler = new AbstractContentTypeHandler() {
|
||||
|
||||
public void toObject(Reader in, Object target) throws IOException {
|
||||
public void toObject(ActionInvocation invocation, Reader in, Object target) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
public String fromObject(Object obj, String resultCode, Writer stream) throws IOException {
|
||||
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer stream) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,6 @@ public class RestWorkflowInterceptorTest extends TestCase {
|
||||
Mock mockActionInvocation = new Mock(ActionInvocation.class);
|
||||
Mock mockActionProxy = new Mock(ActionProxy.class);
|
||||
mockActionProxy.expectAndReturn("getConfig", null);
|
||||
mockActionInvocation.expectAndReturn("getProxy", mockActionProxy.proxy());
|
||||
mockActionInvocation.expectAndReturn("getAction", action);
|
||||
Mock mockContentTypeHandlerManager = new Mock(ContentTypeHandlerManager.class);
|
||||
mockContentTypeHandlerManager.expectAndReturn("handleResult", new AnyConstraintMatcher() {
|
||||
|
||||
+5
-4
@@ -21,6 +21,7 @@
|
||||
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import com.opensymphony.xwork2.mock.MockActionInvocation;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -37,7 +38,7 @@ public class JacksonLibHandlerTest extends TestCase {
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
JacksonLibHandler handler = new JacksonLibHandler();
|
||||
handler.fromObject(contact, "success", writer);
|
||||
handler.fromObject(new MockActionInvocation(), contact, "success", writer);
|
||||
String data = writer.toString();
|
||||
assertTrue(data.startsWith("{"));
|
||||
assertTrue(data.contains("\"age\":44"));
|
||||
@@ -50,7 +51,7 @@ public class JacksonLibHandlerTest extends TestCase {
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
JacksonLibHandler handler = new JacksonLibHandler();
|
||||
handler.fromObject(Arrays.asList(contact), "success", writer);
|
||||
handler.fromObject(new MockActionInvocation(), Arrays.asList(contact), "success", writer);
|
||||
|
||||
String data = writer.toString();
|
||||
assertTrue(data.startsWith("[{"));
|
||||
@@ -65,7 +66,7 @@ public class JacksonLibHandlerTest extends TestCase {
|
||||
Contact target = new Contact();
|
||||
StringReader reader = new StringReader("{\"age\":44,\"important\":true,\"name\":\"bob\"}");
|
||||
JacksonLibHandler handler = new JacksonLibHandler();
|
||||
handler.toObject(reader, target);
|
||||
handler.toObject(new MockActionInvocation(), reader, target);
|
||||
assertEquals(contact, target);
|
||||
}
|
||||
|
||||
@@ -78,7 +79,7 @@ public class JacksonLibHandlerTest extends TestCase {
|
||||
List<Contact> target = new ArrayList<Contact>();
|
||||
StringReader reader = new StringReader("[{\"age\":44,\"important\":true,\"name\":\"bob\"},{\"age\":33,\"important\":false,\"name\":\"john\"}]");
|
||||
JacksonLibHandler handler = new JacksonLibHandler();
|
||||
handler.toObject(reader, target);
|
||||
handler.toObject(new MockActionInvocation(), reader, target);
|
||||
assertEquals(source.size(), target.size());
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.opensymphony.xwork2.mock.MockActionInvocation;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class JsonLibHandlerTest extends TestCase {
|
||||
@@ -35,7 +36,7 @@ public class JsonLibHandlerTest extends TestCase {
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
JsonLibHandler handler = new JsonLibHandler();
|
||||
handler.fromObject(contact, "success", writer);
|
||||
handler.fromObject(new MockActionInvocation(), contact, "success", writer);
|
||||
String data = writer.toString();
|
||||
assertTrue(data.startsWith("{"));
|
||||
assertTrue(data.contains("\"age\":44"));
|
||||
@@ -48,7 +49,7 @@ public class JsonLibHandlerTest extends TestCase {
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
JsonLibHandler handler = new JsonLibHandler();
|
||||
handler.fromObject(Arrays.asList(contact), "success", writer);
|
||||
handler.fromObject(new MockActionInvocation(), Arrays.asList(contact), "success", writer);
|
||||
|
||||
String data = writer.toString();
|
||||
assertTrue(data.startsWith("[{"));
|
||||
@@ -63,7 +64,7 @@ public class JsonLibHandlerTest extends TestCase {
|
||||
Contact target = new Contact();
|
||||
StringReader reader = new StringReader("{\"age\":44,\"important\":true,\"name\":\"bob\"}");
|
||||
JsonLibHandler handler = new JsonLibHandler();
|
||||
handler.toObject(reader, target);
|
||||
handler.toObject(new MockActionInvocation(), reader, target);
|
||||
|
||||
assertEquals(contact, target);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-sitegraph-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-sitemesh-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-spring-plugin</artifactId>
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
<constant name="struts.class.reloading.watchList" value="" />
|
||||
<constant name="struts.class.reloading.acceptClasses" value="" />
|
||||
<constant name="struts.class.reloading.reloadConfig" value="false" />
|
||||
<constant name="xwork.disallowProxyMemberAccess" value="true" />
|
||||
|
||||
<package name="spring-default">
|
||||
<interceptors>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-struts1-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-testng-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-tiles-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-tiles3-plugin</artifactId>
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts-master</artifactId>
|
||||
<version>9</version>
|
||||
<version>11</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Struts 2</name>
|
||||
<url>http://struts.apache.org/</url>
|
||||
@@ -31,7 +31,7 @@
|
||||
<connection>scm:git:git://git.apache.org/struts.git</connection>
|
||||
<developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/struts.git</developerConnection>
|
||||
<url>http://git.apache.org/struts.git</url>
|
||||
<tag>STRUTS_2_3_31</tag>
|
||||
<tag>STRUTS_2_3_34</tag>
|
||||
</scm>
|
||||
|
||||
<issueManagement>
|
||||
@@ -86,7 +86,7 @@
|
||||
<properties>
|
||||
<currentVersion>${project.version}</currentVersion>
|
||||
<struts2.springPlatformVersion>3.0.5.RELEASE</struts2.springPlatformVersion>
|
||||
<ognl.version>3.0.19</ognl.version>
|
||||
<ognl.version>3.0.21</ognl.version>
|
||||
<asm.version>3.3</asm.version>
|
||||
<asm5.version>5.0.2</asm5.version>
|
||||
<tiles.version>2.2.2</tiles.version>
|
||||
@@ -940,7 +940,7 @@
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<version>1.4.8</version>
|
||||
<version>1.4.10</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.3.31</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.apache.struts.xwork</groupId>
|
||||
|
||||
@@ -28,4 +28,5 @@ public final class XWorkConstants {
|
||||
public static final String OVERRIDE_EXCLUDED_PATTERNS = "overrideExcludedPatterns";
|
||||
public static final String OVERRIDE_ACCEPTED_PATTERNS = "overrideAcceptedPatterns";
|
||||
|
||||
public static final String XWORK_DISALLOW_PROXY_MEMBER_ACCESS = "xwork.disallowProxyMemberAccess";
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ public class OgnlUtil {
|
||||
|
||||
private Container container;
|
||||
private boolean allowStaticMethodAccess;
|
||||
private boolean disallowProxyMemberAccess;
|
||||
|
||||
@Inject
|
||||
public void setXWorkConverter(XWorkConverter conv) {
|
||||
@@ -144,6 +145,15 @@ public class OgnlUtil {
|
||||
this.allowStaticMethodAccess = Boolean.parseBoolean(allowStaticMethodAccess);
|
||||
}
|
||||
|
||||
@Inject(value = XWorkConstants.XWORK_DISALLOW_PROXY_MEMBER_ACCESS, required = false)
|
||||
public void setDisallowProxyMemberAccess(String disallowProxyMemberAccess) {
|
||||
this.disallowProxyMemberAccess = Boolean.parseBoolean(disallowProxyMemberAccess);
|
||||
}
|
||||
|
||||
public boolean isDisallowProxyMemberAccess() {
|
||||
return disallowProxyMemberAccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the object's properties using the default type converter, defaulting to not throw
|
||||
* exceptions for problems setting the properties.
|
||||
@@ -654,6 +664,7 @@ public class OgnlUtil {
|
||||
memberAccess.setExcludedClasses(excludedClasses);
|
||||
memberAccess.setExcludedPackageNamePatterns(excludedPackageNamePatterns);
|
||||
memberAccess.setExcludedPackageNames(excludedPackageNames);
|
||||
memberAccess.setDisallowProxyMemberAccess(disallowProxyMemberAccess);
|
||||
|
||||
return Ognl.createDefaultContext(root, resolver, defaultConverter, memberAccess);
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
|
||||
securityMemberAccess.setExcludedClasses(ognlUtil.getExcludedClasses());
|
||||
securityMemberAccess.setExcludedPackageNamePatterns(ognlUtil.getExcludedPackageNamePatterns());
|
||||
securityMemberAccess.setExcludedPackageNames(ognlUtil.getExcludedPackageNames());
|
||||
securityMemberAccess.setDisallowProxyMemberAccess(ognlUtil.isDisallowProxyMemberAccess());
|
||||
}
|
||||
|
||||
protected void setRoot(XWorkConverter xworkConverter, CompoundRootAccessor accessor, CompoundRoot compoundRoot,
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.opensymphony.xwork2.ognl;
|
||||
|
||||
import com.opensymphony.xwork2.util.ProxyUtil;
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
import ognl.DefaultMemberAccess;
|
||||
@@ -41,6 +42,7 @@ public class SecurityMemberAccess extends DefaultMemberAccess {
|
||||
private Set<Class<?>> excludedClasses = Collections.emptySet();
|
||||
private Set<Pattern> excludedPackageNamePatterns = Collections.emptySet();
|
||||
private Set<String> excludedPackageNames = Collections.emptySet();
|
||||
private boolean disallowProxyMemberAccess;
|
||||
|
||||
public SecurityMemberAccess(boolean method) {
|
||||
super(false);
|
||||
@@ -93,6 +95,11 @@ public class SecurityMemberAccess extends DefaultMemberAccess {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (disallowProxyMemberAccess && ProxyUtil.isProxyMember(member, target)) {
|
||||
LOG.warn("Access to proxy [#0] is blocked!", member);
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean allow = true;
|
||||
if (!checkStaticMethodAccess(member)) {
|
||||
if (LOG.isTraceEnabled()) {
|
||||
@@ -216,4 +223,8 @@ public class SecurityMemberAccess extends DefaultMemberAccess {
|
||||
public void setExcludedPackageNames(Set<String> excludedPackageNames) {
|
||||
this.excludedPackageNames = excludedPackageNames;
|
||||
}
|
||||
|
||||
public void setDisallowProxyMemberAccess(boolean disallowProxyMemberAccess) {
|
||||
this.disallowProxyMemberAccess = disallowProxyMemberAccess;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 2017 The Apache Software Foundation.
|
||||
*
|
||||
* 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 com.opensymphony.xwork2.util;
|
||||
|
||||
import org.apache.commons.lang3.reflect.ConstructorUtils;
|
||||
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||
import org.apache.commons.lang3.reflect.MethodUtils;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* <code>ProxyUtil</code>
|
||||
* <p>
|
||||
* Various utility methods dealing with proxies
|
||||
* </p>
|
||||
*
|
||||
*/
|
||||
public class ProxyUtil {
|
||||
private static final String SPRING_ADVISED_CLASS_NAME = "org.springframework.aop.framework.Advised";
|
||||
private static final String SPRING_SPRINGPROXY_CLASS_NAME = "org.springframework.aop.SpringProxy";
|
||||
private static final String SPRING_TARGETCLASSAWARE_CLASS_NAME = "org.springframework.aop.TargetClassAware";
|
||||
|
||||
private static final Map<Class<?>, Boolean> isProxyCache =
|
||||
new ConcurrentHashMap<Class<?>, Boolean>(256);
|
||||
private static final Map<Member, Boolean> isProxyMemberCache =
|
||||
new ConcurrentHashMap<Member, Boolean>(256);
|
||||
|
||||
/**
|
||||
* Check whether the given member is a proxy member of a proxy object.
|
||||
* @param member the member to check
|
||||
* @param object the object to check
|
||||
*/
|
||||
public static boolean isProxyMember(Member member, Object object) {
|
||||
if (!isProxy(object))
|
||||
return false;
|
||||
|
||||
Boolean flag = isProxyMemberCache.get(member);
|
||||
if (flag != null) {
|
||||
return flag;
|
||||
}
|
||||
|
||||
boolean isProxyMember = isSpringProxyMember(member);
|
||||
|
||||
isProxyMemberCache.put(member, isProxyMember);
|
||||
return isProxyMember;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given object is a proxy.
|
||||
* @param object the object to check
|
||||
*/
|
||||
private static boolean isProxy(Object object) {
|
||||
Class<?> clazz = object.getClass();
|
||||
Boolean flag = isProxyCache.get(clazz);
|
||||
if (flag != null) {
|
||||
return flag;
|
||||
}
|
||||
|
||||
boolean isProxy = isSpringAopProxy(object);
|
||||
|
||||
isProxyCache.put(clazz, isProxy);
|
||||
return isProxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given object is a Spring proxy.
|
||||
* @param object the object to check
|
||||
*/
|
||||
private static boolean isSpringAopProxy(Object object) {
|
||||
Class<?> clazz = object.getClass();
|
||||
return (implementsInterface(clazz, SPRING_SPRINGPROXY_CLASS_NAME) && (Proxy.isProxyClass(clazz)
|
||||
|| isCglibProxyClass(clazz)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given member is a member of a spring proxy.
|
||||
* @param member the member to check
|
||||
*/
|
||||
private static boolean isSpringProxyMember(Member member) {
|
||||
try {
|
||||
Class<?> clazz = ClassLoaderUtil.loadClass(SPRING_ADVISED_CLASS_NAME, ProxyUtil.class);
|
||||
if (hasMember(clazz, member))
|
||||
return true;
|
||||
clazz = ClassLoaderUtil.loadClass(SPRING_TARGETCLASSAWARE_CLASS_NAME, ProxyUtil.class);
|
||||
if (hasMember(clazz, member))
|
||||
return true;
|
||||
clazz = ClassLoaderUtil.loadClass(SPRING_SPRINGPROXY_CLASS_NAME, ProxyUtil.class);
|
||||
if (hasMember(clazz, member))
|
||||
return true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the specified class is a CGLIB-generated class.
|
||||
* @param clazz the class to check
|
||||
*/
|
||||
private static boolean isCglibProxyClass(Class<?> clazz) {
|
||||
return (clazz != null && clazz.getName().contains("$$"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given class implements an interface with a given class name.
|
||||
* @param clazz the class to check
|
||||
* @param ifaceClassName the interface class name to check
|
||||
*/
|
||||
private static boolean implementsInterface(Class<?> clazz, String ifaceClassName) {
|
||||
try {
|
||||
Class<?> ifaceClass = ClassLoaderUtil.loadClass(ifaceClassName, ProxyUtil.class);
|
||||
return ifaceClass.isAssignableFrom(clazz);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given class has a given member.
|
||||
* @param clazz the class to check
|
||||
* @param member the member to check
|
||||
*/
|
||||
private static boolean hasMember(Class<?> clazz, Member member) {
|
||||
if (member instanceof Method) {
|
||||
return null != MethodUtils.getMatchingAccessibleMethod(clazz, member.getName(), ((Method) member).getParameterTypes());
|
||||
}
|
||||
if (member instanceof Field) {
|
||||
return null != FieldUtils.getField(clazz, member.getName(), true);
|
||||
}
|
||||
if (member instanceof Constructor) {
|
||||
return null != ConstructorUtils.getMatchingAccessibleConstructor(clazz, ((Constructor) member).getParameterTypes());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+2
-4
@@ -23,7 +23,7 @@ package com.opensymphony.xwork2.validator.validators;
|
||||
* The regular expression used to validate that the string is an email address is:
|
||||
*
|
||||
* <pre>
|
||||
* \\b^['_a-z0-9-\\+]+(\\.['_a-z0-9-\\+]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2}|aero|arpa|asia|biz|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|nato|net|org|pro|tel|travel|xxx|tech|cat)$\\b
|
||||
* \\b^['_a-z0-9-\\+]+(\\.['_a-z0-9-\\+]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2,6})$\\b
|
||||
* </pre>
|
||||
*
|
||||
* You can also specify expression, caseSensitive and trim params as a OGNL expression, see the example below.
|
||||
@@ -78,9 +78,7 @@ package com.opensymphony.xwork2.validator.validators;
|
||||
*/
|
||||
public class EmailValidator extends RegexFieldValidator {
|
||||
|
||||
// see XW-371
|
||||
public static final String EMAIL_ADDRESS_PATTERN =
|
||||
"\\b^['_a-z0-9-\\+]+(\\.['_a-z0-9-\\+]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2}|aero|arpa|asia|biz|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|nato|net|org|pro|tel|travel|xxx|tech|cat)$\\b";
|
||||
public static final String EMAIL_ADDRESS_PATTERN = "\\b^['_a-z0-9-\\+]+(\\.['_a-z0-9-\\+]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2,6})$\\b";
|
||||
|
||||
public EmailValidator() {
|
||||
setRegex(EMAIL_ADDRESS_PATTERN);
|
||||
|
||||
+11
-12
@@ -73,19 +73,18 @@ public class URLValidator extends FieldValidatorSupport {
|
||||
} else if (StringUtils.isNotEmpty(urlRegex)) {
|
||||
return urlRegex;
|
||||
} else {
|
||||
return "^(https?|ftp):\\/\\/" +
|
||||
"(([a-z0-9$_\\.\\+!\\*\\'\\(\\),;\\?&=-]|%[0-9a-f]{2})+" +
|
||||
"(:([a-z0-9$_\\.\\+!\\*\\'\\(\\),;\\?&=-]|%[0-9a-f]{2})+)?" +
|
||||
"@)?(#?" +
|
||||
")((([a-z0-9]\\.|[a-z0-9][a-z0-9-]*[a-z0-9]\\.)*" +
|
||||
return "^(?:https?|ftp):\\/\\/" +
|
||||
"(?:(?:[a-z0-9$_.+!*'(),;?&=\\-]|%[0-9a-f]{2})+" +
|
||||
"(?::(?:[a-z0-9$_.+!*'(),;?&=\\-]|%[0-9a-f]{2})+)?" +
|
||||
"@)?#?" +
|
||||
"(?:(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)*" +
|
||||
"[a-z][a-z0-9-]*[a-z0-9]" +
|
||||
"|((\\d|[1-9]\\d|1\\d{2}|2[0-4][0-9]|25[0-5])\\.){3}" +
|
||||
"(\\d|[1-9]\\d|1\\d{2}|2[0-4][0-9]|25[0-5])" +
|
||||
")(:\\d+)?" +
|
||||
")(((\\/{0,1}([a-z0-9$_\\.\\+!\\*\\'\\(\\),;:@&=-]|%[0-9a-f]{2})*)*" +
|
||||
"(\\?([a-z0-9$_\\.\\+!\\*\\'\\(\\),;:@&=-]|%[0-9a-f]{2})*)" +
|
||||
"?)?)?" +
|
||||
"(#([a-z0-9$_\\.\\+!\\*\\'\\(\\),;:@&=-]|%[0-9a-f]{2})*)?" +
|
||||
"|(?:(?:[1-9]?\\d|1\\d{2}|2[0-4]\\d|25[0-5])\\.){3}" +
|
||||
"(?:[1-9]?\\d|1\\d{2}|2[0-4]\\d|25[0-5])" +
|
||||
")(?::\\d+)?" +
|
||||
")(?:(?:\\/(?:[a-z0-9$_.+!*'(),;:@&=\\-]|%[0-9a-f]{2})*)*" +
|
||||
"(?:\\?(?:[a-z0-9$_.+!*'(),;:@&=\\-\\/:]|%[0-9a-f]{2})*)?)?" +
|
||||
"(?:#(?:[a-z0-9$_.+!*'(),;:@&=\\-]|%[0-9a-f]{2})*)?" +
|
||||
"$";
|
||||
}
|
||||
}
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.opensymphony.xwork2.ognl;
|
||||
|
||||
import java.lang.reflect.Member;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.opensymphony.xwork2.ActionProxy;
|
||||
import com.opensymphony.xwork2.XWorkTestCase;
|
||||
import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
|
||||
|
||||
public class SecurityMemberAccessProxyTest extends XWorkTestCase {
|
||||
private Map<String, Object> context;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
context = new HashMap<String, Object>();
|
||||
// Set up XWork
|
||||
XmlConfigurationProvider provider = new XmlConfigurationProvider("com/opensymphony/xwork2/spring/actionContext-xwork.xml");
|
||||
container.inject(provider);
|
||||
loadConfigurationProviders(provider);
|
||||
}
|
||||
|
||||
public void testProxyAccessIsBlocked() throws Exception {
|
||||
ActionProxy proxy = actionProxyFactory.createActionProxy(null,
|
||||
"paramsAwareProxiedAction", null, context);
|
||||
|
||||
SecurityMemberAccess sma = new SecurityMemberAccess(false);
|
||||
sma.setDisallowProxyMemberAccess(true);
|
||||
|
||||
Member member = proxy.getAction().getClass().getMethod("isExposeProxy");
|
||||
|
||||
boolean accessible = sma.isAccessible(context, proxy.getAction(), member, "");
|
||||
assertFalse(accessible);
|
||||
}
|
||||
|
||||
public void testProxyAccessIsAccessible() throws Exception {
|
||||
ActionProxy proxy = actionProxyFactory.createActionProxy(null,
|
||||
"paramsAwareProxiedAction", null, context);
|
||||
|
||||
SecurityMemberAccess sma = new SecurityMemberAccess(false);
|
||||
|
||||
Member member = proxy.getAction().getClass().getMethod("isExposeProxy");
|
||||
|
||||
boolean accessible = sma.isAccessible(context, proxy.getAction(), member, "");
|
||||
assertTrue(accessible);
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,12 @@ package com.opensymphony.xwork2.spring;
|
||||
|
||||
import com.opensymphony.xwork2.*;
|
||||
import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
|
||||
import org.apache.commons.lang3.reflect.MethodUtils;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Test loading actions from the Spring Application Context.
|
||||
*
|
||||
@@ -77,4 +81,26 @@ public class ActionsFromSpringTest extends XWorkTestCase {
|
||||
assertTrue(springResult.isInitialize());
|
||||
assertNotNull(springResult.getStringParameter());
|
||||
}
|
||||
|
||||
public void testProxiedActionIsNotAccessible() throws Exception {
|
||||
// given
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put("exposeProxy", "true");
|
||||
params.put("blah", "S2-047");
|
||||
|
||||
HashMap<String, Object> extraContext = new HashMap<String, Object>();
|
||||
extraContext.put(ActionContext.PARAMETERS, params);
|
||||
|
||||
ActionProxy proxy = actionProxyFactory.createActionProxy(null,
|
||||
"paramsAwareProxiedAction", null, extraContext);
|
||||
|
||||
// when
|
||||
proxy.execute();
|
||||
Object action = proxy.getAction();
|
||||
|
||||
//then
|
||||
assertEquals("S2-047", ((SimpleAction) action).getBlah());
|
||||
assertFalse("proxied action is accessible!",
|
||||
(Boolean) MethodUtils.invokeMethod(action, "isExposeProxy"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.opensymphony.xwork2.validator;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.XWorkTestCase;
|
||||
import com.opensymphony.xwork2.util.URLUtil;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.validator.validators.URLValidator;
|
||||
|
||||
@@ -132,14 +131,18 @@ public class URLValidatorTest extends XWorkTestCase {
|
||||
public void testValidUrlWithDefaultRegex() throws Exception {
|
||||
URLValidator validator = new URLValidator();
|
||||
|
||||
Pattern pattern = Pattern.compile(validator.getUrlRegex());
|
||||
Pattern pattern = Pattern.compile(validator.getUrlRegex(), Pattern.CASE_INSENSITIVE);
|
||||
|
||||
assertFalse(pattern.matcher("myapp://test.com").matches());
|
||||
assertFalse(pattern.matcher("myap://test.com").matches());
|
||||
assertFalse(pattern.matcher("").matches());
|
||||
assertFalse(pattern.matcher(" ").matches());
|
||||
assertFalse(pattern.matcher("no url").matches());
|
||||
assertFalse(pattern.matcher("http://example.com////////////////////////////////////////////////////////////////////////////////////??").matches());
|
||||
assertFalse(pattern.matcher("http://example.com////////////////////////////////////////////////////////////////////////////////////??").matches());
|
||||
|
||||
assertTrue(pattern.matcher("http://www.legalspace.com/__media__/js/netsoltrademark.php?d=www.a-vos-travaux.fr%2Facheter-un-aspirateur-sans-sac-pas-cher%2F").matches());
|
||||
assertTrue(pattern.matcher("http://www.duadmin.isaev.Infoduadmin.Isaev.info/?a%5B%5D=%3Ca%20href%3Dhttp%3A%2F%2Fwww.aspert.fr%2Fun-seche-cheveux-lisseur-est-il-vraiment-utile%2F%3Eseche%20cheveux%20dyson%20test%3C%2Fa").matches());
|
||||
assertTrue(pattern.matcher("http://netsol-underconstruction-page-monitor-1.com/__media__/js/netsoltrademark.php?d=www.le-soutien-scolaire.fr%2Favis-et-test-comparatifs-des-robots-multifonctions%2F").matches());
|
||||
|
||||
assertTrue(pattern.matcher("http://www.opensymphony.com").matches());
|
||||
assertTrue(pattern.matcher("https://www.opensymphony.com").matches());
|
||||
@@ -181,7 +184,7 @@ public class URLValidatorTest extends XWorkTestCase {
|
||||
}
|
||||
|
||||
public String getTestingUrl5() {
|
||||
return "http://yahoo.com/articles?id=123";
|
||||
return "http://yahoo.com/articles?id=123\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,18 @@
|
||||
<xwork>
|
||||
<bean type="com.opensymphony.xwork2.ObjectFactory" class="com.opensymphony.xwork2.spring.SpringObjectFactory" />
|
||||
<constant name="applicationContextPath" value="com/opensymphony/xwork2/spring/actionContext-spring.xml" />
|
||||
<constant name="xwork.disallowProxyMemberAccess" value="true" />
|
||||
<package name="default">
|
||||
<result-types>
|
||||
<result-type name="null" class="com.opensymphony.xwork2.mock.MockResult" default="true"/>
|
||||
<result-type name="springResult" class="springResult" />
|
||||
</result-types>
|
||||
|
||||
<interceptors>
|
||||
<interceptor name="params"
|
||||
class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
|
||||
</interceptors>
|
||||
|
||||
<action name="simpleAction" class="simple-action"/>
|
||||
|
||||
<action name="dependencyAction" class="dependency-action"/>
|
||||
@@ -19,5 +25,10 @@
|
||||
<action name="simpleActionSpringResult" class="simple-action">
|
||||
<result name="error" type="springResult"/>
|
||||
</action>
|
||||
|
||||
<action name="paramsAwareProxiedAction" class="proxied-action">
|
||||
<interceptor-ref name="params" />
|
||||
<result name="input" type="null"/>
|
||||
</action>
|
||||
</package>
|
||||
</xwork>
|
||||
|
||||
Reference in New Issue
Block a user