This is an automated email from the ASF dual-hosted git repository.
nmalin pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
The following commit(s) were added to refs/heads/trunk by this push:
new 0fce1dd56c Improved: Improve ViewHandler interface (OFBIZ-13179) (#858)
0fce1dd56c is described below
commit 0fce1dd56c76e3dde0d27085ddd90d692560a8e2
Author: Nicolas Malin <[email protected]>
AuthorDate: Thu Nov 28 17:19:50 2024 +0100
Improved: Improve ViewHandler interface (OFBIZ-13179) (#858)
We extend *AbstractViewHandler* with a new method to override
*prepareViewContext*.
For each view handler implementation this will allow to control context
used for rendering, applying Scriptlet token detection for security purpose.
A new class *SecuredFreemarker* has been created to manage freemarker
specific controls, outside global *SecurityUtil* class.
We also add a new parameter *secure-context* (set true by default) to
view-map xml element to indicate that this view allow unsecure rendering, this
implies the view-map to required authentication.
Thanks to Gil Portenseigne for help
---
.../org/apache/ofbiz/content/cms/CmsEvents.java | 2 +-
.../content/view/SimpleContentViewHandler.java | 37 ++++--
.../ofbiz/product/category/SeoContextFilter.java | 4 +-
.../apache/ofbiz/security/SecuredFreemarker.java | 131 +++++++++++++++++++++
.../org/apache/ofbiz/security/SecurityUtil.java | 72 -----------
framework/webapp/dtd/site-conf.xsd | 10 ++
.../ofbiz/webapp/control/ConfigXMLReader.java | 13 +-
.../apache/ofbiz/webapp/control/ControlFilter.java | 7 +-
.../ofbiz/webapp/control/RequestHandler.java | 3 +-
.../ofbiz/webapp/ftl/FreeMarkerViewHandler.java | 59 +++++-----
.../apache/ofbiz/webapp/view/HttpViewHandler.java | 9 +-
.../apache/ofbiz/webapp/view/JspViewHandler.java | 19 ++-
.../org/apache/ofbiz/webapp/view/ViewHandler.java | 14 ++-
.../ofbiz/widget/renderer/ScreenRenderer.java | 13 +-
.../widget/renderer/fo/ScreenFopViewHandler.java | 75 +++++++-----
.../renderer/macro/MacroScreenViewHandler.java | 15 ++-
16 files changed, 314 insertions(+), 169 deletions(-)
diff --git
a/applications/content/src/main/java/org/apache/ofbiz/content/cms/CmsEvents.java
b/applications/content/src/main/java/org/apache/ofbiz/content/cms/CmsEvents.java
index 173ecaaa91..2012f2d5cc 100644
---
a/applications/content/src/main/java/org/apache/ofbiz/content/cms/CmsEvents.java
+++
b/applications/content/src/main/java/org/apache/ofbiz/content/cms/CmsEvents.java
@@ -294,7 +294,7 @@ public final class CmsEvents {
if (statusCode == HttpServletResponse.SC_OK || hasErrorPage) {
// create the template map
MapStack<String> templateMap = MapStack.create();
- ScreenRenderer.populateContextForRequest(templateMap,
null, request, response, servletContext);
+ ScreenRenderer.populateContextForRequest(templateMap,
null, request, response, servletContext, true);
templateMap.put("statusCode", statusCode);
// make the link prefix
diff --git
a/applications/content/src/main/java/org/apache/ofbiz/content/view/SimpleContentViewHandler.java
b/applications/content/src/main/java/org/apache/ofbiz/content/view/SimpleContentViewHandler.java
index 8b697f0358..ae177cd102 100644
---
a/applications/content/src/main/java/org/apache/ofbiz/content/view/SimpleContentViewHandler.java
+++
b/applications/content/src/main/java/org/apache/ofbiz/content/view/SimpleContentViewHandler.java
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.sql.Timestamp;
import java.text.ParseException;
+import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -44,9 +45,11 @@ import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.util.EntityQuery;
import org.apache.ofbiz.entity.util.EntityUtilProperties;
+import org.apache.ofbiz.security.SecuredFreemarker;
import org.apache.ofbiz.service.GenericServiceException;
import org.apache.ofbiz.service.LocalDispatcher;
import org.apache.ofbiz.service.ServiceUtil;
+import org.apache.ofbiz.webapp.control.ConfigXMLReader;
import org.apache.ofbiz.webapp.view.AbstractViewHandler;
import org.apache.ofbiz.webapp.view.ViewHandlerException;
import org.apache.ofbiz.webapp.website.WebSiteWorker;
@@ -62,24 +65,36 @@ public class SimpleContentViewHandler extends
AbstractViewHandler {
rootDir = context.getRealPath("/");
https = (String) context.getAttribute("https");
}
+
+ @Override
+ public Map<String, Object> prepareViewContext(HttpServletRequest request,
HttpServletResponse response, ConfigXMLReader.ViewMap viewMap) {
+ List<String> fields = List.of("contentId", "rootContentId", "mapKey",
+ "contentAssocTypeId", "fromDate", "dataResourceId",
+ "contentRevisionSeqId", "mimeTypeId");
+ Map<String, Object> context = new HashMap<>();
+ fields.forEach(field -> context.put(field,
request.getParameter(field)));
+ return viewMap.isSecureContext()
+ ? SecuredFreemarker.sanitizeParameterMap(context)
+ : context;
+ }
+
/**
- * @see org.apache.ofbiz.webapp.view.ViewHandler#render(java.lang.String,
java.lang.String, java.lang.String, java.lang.String,
- * java.lang.String, javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse)
+ * @see org.apache.ofbiz.webapp.view.ViewHandler#render(String, String,
String, String, String, HttpServletRequest, HttpServletResponse, Map)
*/
@Override
public void render(String name, String page, String info, String
contentType, String encoding, HttpServletRequest request,
- HttpServletResponse response) throws
ViewHandlerException {
+ HttpServletResponse response, Map<String, Object>
context) throws ViewHandlerException {
LocalDispatcher dispatcher = (LocalDispatcher)
request.getAttribute("dispatcher");
HttpSession session = request.getSession();
GenericValue userLogin = (GenericValue)
session.getAttribute("userLogin");
- String contentId = request.getParameter("contentId");
- String rootContentId = request.getParameter("rootContentId");
- String mapKey = request.getParameter("mapKey");
- String contentAssocTypeId = request.getParameter("contentAssocTypeId");
- String fromDateStr = request.getParameter("fromDate");
- String dataResourceId = request.getParameter("dataResourceId");
- String contentRevisionSeqId =
request.getParameter("contentRevisionSeqId");
- String mimeTypeId = request.getParameter("mimeTypeId");
+ String contentId = (String) context.get("contentId");
+ String rootContentId = (String) context.get("rootContentId");
+ String mapKey = (String) context.get("mapKey");
+ String contentAssocTypeId = (String) context.get("contentAssocTypeId");
+ String fromDateStr = (String) context.get("fromDate");
+ String dataResourceId = (String) context.get("dataResourceId");
+ String contentRevisionSeqId = (String)
context.get("contentRevisionSeqId");
+ String mimeTypeId = (String) context.get("mimeTypeId");
Locale locale = UtilHttp.getLocale(request);
String webSiteId = WebSiteWorker.getWebSiteId(request);
diff --git
a/applications/product/src/main/java/org/apache/ofbiz/product/category/SeoContextFilter.java
b/applications/product/src/main/java/org/apache/ofbiz/product/category/SeoContextFilter.java
index bea4d8a7ae..0b7e638782 100644
---
a/applications/product/src/main/java/org/apache/ofbiz/product/category/SeoContextFilter.java
+++
b/applications/product/src/main/java/org/apache/ofbiz/product/category/SeoContextFilter.java
@@ -48,7 +48,7 @@ import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.StringUtil;
import org.apache.ofbiz.base.util.UtilHttp;
import org.apache.ofbiz.base.util.UtilValidate;
-import org.apache.ofbiz.security.SecurityUtil;
+import org.apache.ofbiz.security.SecuredFreemarker;
import org.apache.ofbiz.webapp.SeoConfigUtil;
import org.apache.ofbiz.webapp.control.ConfigXMLReader;
import org.apache.ofbiz.webapp.control.ConfigXMLReader.ControllerConfig;
@@ -116,7 +116,7 @@ public final class SeoContextFilter implements Filter {
uri = uri + "?" + queryString;
}
- if (SecurityUtil.containsFreemarkerInterpolation(httpRequest,
httpResponse, uri)) {
+ if (SecuredFreemarker.containsFreemarkerInterpolation(httpRequest,
httpResponse, uri)) {
return;
}
diff --git
a/framework/security/src/main/java/org/apache/ofbiz/security/SecuredFreemarker.java
b/framework/security/src/main/java/org/apache/ofbiz/security/SecuredFreemarker.java
new file mode 100644
index 0000000000..b0b788d0ec
--- /dev/null
+++
b/framework/security/src/main/java/org/apache/ofbiz/security/SecuredFreemarker.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * 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.ofbiz.security;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.http.client.utils.URLEncodedUtils;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.ofbiz.base.util.Debug;
+import org.apache.ofbiz.base.util.StringUtil;
+import org.apache.ofbiz.base.util.UtilHttp;
+import org.apache.ofbiz.base.util.UtilProperties;
+import org.apache.ofbiz.base.util.UtilValidate;
+
+public class SecuredFreemarker {
+ private static final String MODULE = SecuredFreemarker.class.getName();
+ private static final List<String> FTL_INTERPOLATION = List.of("%24%7B",
"${", "%3C%23", "<#", "%23%7B", "#{", "%5B%3D", "[=", "%5B%23", "[#");
+
+ /*
+ * Prevents Freemarker exploits
+ * @param req
+ * @param resp
+ * @param uri
+ * @throws IOException
+ */
+ public static boolean containsFreemarkerInterpolation(HttpServletRequest
req, HttpServletResponse resp, String uri)
+ throws IOException {
+ String urisOkForFreemarker =
UtilProperties.getPropertyValue("security",
"allowedURIsForFreemarkerInterpolation");
+ List<String> urisOK = UtilValidate.isNotEmpty(urisOkForFreemarker) ?
StringUtil.split(urisOkForFreemarker, ",")
+ :
new ArrayList<>();
+ String uriEnd = uri.substring(uri.lastIndexOf("/") + 1, uri.length());
+
+ if (!urisOK.contains(uriEnd)) {
+ Map<String, String[]> parameterMap = req.getParameterMap();
+ if (uri.contains("ecomseo")) { // SeoContextFilter call
+ if (containsFreemarkerInterpolation(resp, uri)) {
+ return true;
+ }
+ } else if (!parameterMap.isEmpty()) { // ControlFilter call
+ List<BasicNameValuePair> params = new ArrayList<>();
+ parameterMap.forEach((name, values) -> {
+ for (String value : values) {
+ params.add(new BasicNameValuePair(name, value));
+ }
+ });
+ String queryString = URLEncodedUtils.format(params,
Charset.forName("UTF-8"));
+ uri = uri + "?" + queryString;
+ if (containsFreemarkerInterpolation(resp, uri)) {
+ return true;
+ }
+ } else if (!UtilHttp.getAttributeMap(req).isEmpty()) { // Call
with Content-Type modified by a MITM attack (rare case)
+ String attributeMap = UtilHttp.getAttributeMap(req).toString();
+ if (containsFreemarkerInterpolation(resp, attributeMap)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @param resp
+ * @param stringToCheck
+ * @throws IOException
+ */
+ public static boolean containsFreemarkerInterpolation(HttpServletResponse
resp, String stringToCheck) throws IOException {
+ if (containsFreemarkerInterpolation(stringToCheck)) { // not used OOTB
in OFBiz, but possible
+ Debug.logError("===== Not saved for security reason, strings '${',
'<#', '#{', '[=' or '[#' not accepted in fields! =====", MODULE);
+ resp.sendError(HttpServletResponse.SC_FORBIDDEN,
+ "Not saved for security reason, strings '${', '<#', '#{',
'[=' or '[#' not accepted in fields!");
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Analyze if stringToCheck contains a freemarker template
+ * @param stringToCheck
+ * @return true if freemarker template is detected
+ */
+ public static boolean containsFreemarkerInterpolation(String
stringToCheck) {
+ return UtilValidate.isNotEmpty(stringToCheck)
+ &&
FTL_INTERPOLATION.stream().anyMatch(stringToCheck::contains);
+ }
+
+ /**
+ * Analyse each entry contains on params. If a freemarker template is
detected, sanatize it to escape any exploit
+ * @param params
+ * @return Map with all values sanitized
+ */
+ public static Map<String, Object> sanitizeParameterMap(Map<String, Object>
params) {
+ List<Map.Entry<String, Object>> unsafeEntries =
params.entrySet().stream()
+ .filter(entry -> entry.getValue() instanceof String
+ && containsFreemarkerInterpolation((String)
entry.getValue()))
+ .toList();
+ if (!unsafeEntries.isEmpty()) {
+ Map<String, Object> paramsSanitize = new HashMap<>(params);
+ unsafeEntries.forEach(entry -> {
+ String sanitazedValue = (String) entry.getValue();
+ for (String interpolation : FTL_INTERPOLATION) {
+ sanitazedValue = sanitazedValue.replace(interpolation,
"##");
+ }
+ paramsSanitize.put(entry.getKey(), sanitazedValue);
+ });
+ return paramsSanitize;
+ }
+ return params;
+ }
+}
diff --git
a/framework/security/src/main/java/org/apache/ofbiz/security/SecurityUtil.java
b/framework/security/src/main/java/org/apache/ofbiz/security/SecurityUtil.java
index 446a1a475c..7648ab49c6 100644
---
a/framework/security/src/main/java/org/apache/ofbiz/security/SecurityUtil.java
+++
b/framework/security/src/main/java/org/apache/ofbiz/security/SecurityUtil.java
@@ -19,23 +19,14 @@
package org.apache.ofbiz.security;
-import java.io.IOException;
-import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.http.client.utils.URLEncodedUtils;
-import org.apache.http.message.BasicNameValuePair;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.StringUtil;
-import org.apache.ofbiz.base.util.UtilHttp;
import org.apache.ofbiz.base.util.UtilMisc;
-import org.apache.ofbiz.base.util.UtilProperties;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericEntityException;
@@ -172,67 +163,4 @@ public final class SecurityUtil {
return false;
}
- /*
- * Prevents Freemarker exploits
- * @param req
- * @param resp
- * @param uri
- * @throws IOException
- */
- public static boolean containsFreemarkerInterpolation(HttpServletRequest
req, HttpServletResponse resp, String uri)
- throws IOException {
- String urisOkForFreemarker =
UtilProperties.getPropertyValue("security",
"allowedURIsForFreemarkerInterpolation");
- List<String> urisOK = UtilValidate.isNotEmpty(urisOkForFreemarker) ?
StringUtil.split(urisOkForFreemarker, ",")
- :
new ArrayList<>();
- String uriEnd = uri.substring(uri.lastIndexOf("/") + 1, uri.length());
-
- if (!urisOK.contains(uriEnd)) {
- Map<String, String[]> parameterMap = req.getParameterMap();
- if (uri.contains("ecomseo")) { // SeoContextFilter call
- if (containsFreemarkerInterpolation(resp, uri)) {
- return true;
- }
- } else if (!parameterMap.isEmpty()) { // ControlFilter call
- List<BasicNameValuePair> params = new ArrayList<>();
- parameterMap.forEach((name, values) -> {
- for (String value : values) {
- params.add(new BasicNameValuePair(name, value));
- }
- });
- String queryString = URLEncodedUtils.format(params,
Charset.forName("UTF-8"));
- uri = uri + "?" + queryString;
- if (SecurityUtil.containsFreemarkerInterpolation(resp, uri)) {
- return true;
- }
- } else if (!UtilHttp.getAttributeMap(req).isEmpty()) { // Call
with Content-Type modified by a MITM attack (rare case)
- String attributeMap = UtilHttp.getAttributeMap(req).toString();
- if (containsFreemarkerInterpolation(resp, attributeMap)) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * @param resp
- * @param stringToCheck
- * @throws IOException
- */
- public static boolean containsFreemarkerInterpolation(HttpServletResponse
resp, String stringToCheck) throws IOException {
- if (stringToCheck.contains("%24%7B") || stringToCheck.contains("${")
- || stringToCheck.contains("%3C%23") ||
stringToCheck.contains("<#")
- || stringToCheck.contains("%23%7B") ||
stringToCheck.contains("#{")
- || stringToCheck.contains("%5B%3D") ||
stringToCheck.contains("[=")
- || stringToCheck.contains("%5B%23") ||
stringToCheck.contains("[#")) { // not used OOTB in OFBiz, but possible
-
- Debug.logError("===== Not saved for security reason, strings '${',
'<#', '#{', '[=' or '[#' not accepted in fields! =====",
- MODULE);
- resp.sendError(HttpServletResponse.SC_FORBIDDEN,
- "Not saved for security reason, strings '${', '<#', '#{',
'[=' or '[#' not accepted in fields!");
- return true;
- } else {
- return false;
- }
- }
}
diff --git a/framework/webapp/dtd/site-conf.xsd
b/framework/webapp/dtd/site-conf.xsd
index cbf2cfde81..79a02b7986 100644
--- a/framework/webapp/dtd/site-conf.xsd
+++ b/framework/webapp/dtd/site-conf.xsd
@@ -792,6 +792,16 @@ under the License.
</xs:documentation>
</xs:annotation>
</xs:attribute>
+ <xs:attribute type="xs:boolean" name="secure-context" default="true">
+ <xs:annotation>
+ <xs:documentation>
+ If secure-context=false, we authorize to forward to the
renderer some parameters with interpretable code.
+ This raise a potential risk of code injection. This can be
usefully for some administration page to
+ configure templating (like ftl for email or dynamic screen
template).
+ For this reason if secure-context=false, auth is set as
true.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
<xs:attribute name="x-frame-options" default="sameorigin">
<xs:annotation>
<xs:documentation>
diff --git
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ConfigXMLReader.java
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ConfigXMLReader.java
index 59c3b91756..d6a16d3856 100644
---
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ConfigXMLReader.java
+++
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ConfigXMLReader.java
@@ -1044,6 +1044,7 @@ public final class ConfigXMLReader {
private String strictTransportSecurity;
private String description;
private boolean noCache = false;
+ private boolean secureContext = true;
private boolean securityAuth = false;
/**
@@ -1105,6 +1106,15 @@ public final class ConfigXMLReader {
return noCache;
}
+ /**
+ * Is secureContext boolean.
+ *
+ * @return the boolean
+ */
+ public boolean isSecureContext() {
+ return secureContext;
+ }
+
/**
* Gets type.
* @return the type
@@ -1144,7 +1154,8 @@ public final class ConfigXMLReader {
this.info = viewMapElement.getAttribute("info");
this.contentType = viewMapElement.getAttribute("content-type");
this.noCache =
"true".equals(viewMapElement.getAttribute("no-cache"));
- this.securityAuth =
"true".equals(viewMapElement.getAttribute("auth"));
+ this.secureContext =
"true".equals(viewMapElement.getAttribute("secure-context"));
+ this.securityAuth =
"true".equals(viewMapElement.getAttribute("auth")) || !this.secureContext;
this.encoding = viewMapElement.getAttribute("encoding");
this.xFrameOption = viewMapElement.getAttribute("x-frame-options");
this.strictTransportSecurity =
viewMapElement.getAttribute("strict-transport-security");
diff --git
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java
index f2c2a5a37d..ca8d2cca69 100644
---
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java
+++
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlFilter.java
@@ -41,11 +41,8 @@ import org.apache.logging.log4j.ThreadContext;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.entity.GenericValue;
+import org.apache.ofbiz.security.SecuredFreemarker;
import org.apache.ofbiz.security.SecuredUpload;
-import org.apache.ofbiz.security.SecurityUtil;
-
-
-
/**
* A Filter used to specify an allowlist of allowed paths to the OFBiz
application.
@@ -166,7 +163,7 @@ public class ControlFilter extends HttpFilter {
GenericValue userLogin = (GenericValue)
session.getAttribute("userLogin");
if (!LoginWorker.hasBasePermission(userLogin, req)) { // Allows
UEL and FlexibleString (OFBIZ-12602)
- if (isSolrTest() &&
SecurityUtil.containsFreemarkerInterpolation(req, resp, uri)) {
+ if (isSolrTest() &&
SecuredFreemarker.containsFreemarkerInterpolation(req, resp, uri)) {
return;
}
}
diff --git
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
index f02efae40f..9ec279ad67 100644
---
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
+++
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
@@ -1285,7 +1285,8 @@ public final class RequestHandler {
Debug.logVerbose("Rendering view [" + nextPage + "] of type ["
+ viewMap.getType() + "]", MODULE);
}
ViewHandler vh = viewFactory.getViewHandler(viewMap.getType());
- vh.render(view, nextPage, viewMap.getInfo(), contentType, charset,
req, resp);
+ Map<String, Object> context = vh.prepareViewContext(req, resp,
viewMap);
+ vh.render(view, nextPage, viewMap.getInfo(), contentType, charset,
req, resp, context);
} catch (ViewHandlerException e) {
Throwable throwable = e.getNested() != null ? e.getNested() : e;
throw new RequestHandlerException(e.getNonNestedMessage(),
throwable);
diff --git
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/FreeMarkerViewHandler.java
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/FreeMarkerViewHandler.java
index aa1974f5ad..05df6ea933 100644
---
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/FreeMarkerViewHandler.java
+++
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/ftl/FreeMarkerViewHandler.java
@@ -30,6 +30,8 @@ import org.apache.ofbiz.base.util.UtilHttp;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.base.util.collections.MapStack;
import org.apache.ofbiz.base.util.template.FreeMarkerWorker;
+import org.apache.ofbiz.security.SecuredFreemarker;
+import org.apache.ofbiz.webapp.control.ConfigXMLReader;
import org.apache.ofbiz.webapp.view.AbstractViewHandler;
import org.apache.ofbiz.webapp.view.ViewHandlerException;
@@ -53,36 +55,10 @@ public class FreeMarkerViewHandler extends
AbstractViewHandler {
}
@Override
- public void render(String name, String page, String info, String
contentType, String encoding,
- HttpServletRequest request, HttpServletResponse response) throws
ViewHandlerException {
- if (UtilValidate.isEmpty(page)) {
- throw new ViewHandlerException("Invalid template source");
- }
-
- // make the root context (data model) for freemarker
- MapStack<String> context = MapStack.create();
- prepOfbizRoot(context, request, response);
-
- // process the template & flush the output
- try {
- if (page.startsWith("component://")) {
- FreeMarkerWorker.renderTemplate(page, context,
response.getWriter());
- } else {
- // backwards compatibility
- Template template = config.getTemplate(page);
- FreeMarkerWorker.renderTemplate(template, context,
response.getWriter());
- }
- response.flushBuffer();
- } catch (TemplateException te) {
- throw new ViewHandlerException("Problems processing Freemarker
template", te);
- } catch (IOException ie) {
- throw new ViewHandlerException("Problems writing to output
stream", ie);
- }
- }
-
- public static void prepOfbizRoot(Map<String, Object> root,
HttpServletRequest request, HttpServletResponse response) {
+ public Map<String, Object> prepareViewContext(HttpServletRequest request,
HttpServletResponse response, ConfigXMLReader.ViewMap viewMap) {
ServletContext servletContext = request.getServletContext();
HttpSession session = request.getSession();
+ MapStack<String> root = MapStack.create();
// add in the OFBiz objects
root.put("delegator", request.getAttribute("delegator"));
@@ -110,11 +86,38 @@ public class FreeMarkerViewHandler extends
AbstractViewHandler {
// add the request parameters -- this now uses a Map from UtilHttp
Map<String, Object> requestParameters =
UtilHttp.getParameterMap(request);
+ if (viewMap.isSecureContext()) {
+ requestParameters =
SecuredFreemarker.sanitizeParameterMap(requestParameters);
+ }
root.put("requestParameters", requestParameters);
// add the TabLibFactory
TaglibFactory jspTaglibs = new TaglibFactory(servletContext);
root.put("JspTaglibs", jspTaglibs);
+ return root;
+ }
+
+ @Override
+ public void render(String name, String page, String info, String
contentType, String encoding,
+ HttpServletRequest request, HttpServletResponse
response, Map<String, Object> context) throws ViewHandlerException {
+ if (UtilValidate.isEmpty(page)) {
+ throw new ViewHandlerException("Invalid template source");
+ }
+ // process the template & flush the output
+ try {
+ if (page.startsWith("component://")) {
+ FreeMarkerWorker.renderTemplate(page, context,
response.getWriter());
+ } else {
+ // backwards compatibility
+ Template template = config.getTemplate(page);
+ FreeMarkerWorker.renderTemplate(template, context,
response.getWriter());
+ }
+ response.flushBuffer();
+ } catch (TemplateException te) {
+ throw new ViewHandlerException("Problems processing Freemarker
template", te);
+ } catch (IOException ie) {
+ throw new ViewHandlerException("Problems writing to output
stream", ie);
+ }
}
}
diff --git
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/HttpViewHandler.java
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/HttpViewHandler.java
index fc8ad691be..f46c4d58df 100644
---
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/HttpViewHandler.java
+++
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/HttpViewHandler.java
@@ -20,6 +20,7 @@ package org.apache.ofbiz.webapp.view;
import java.io.IOException;
+import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -28,6 +29,7 @@ import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.HttpClient;
import org.apache.ofbiz.base.util.HttpClientException;
import org.apache.ofbiz.base.util.UtilValidate;
+import org.apache.ofbiz.webapp.control.ConfigXMLReader;
/**
* ViewHandlerException - View Handler Exception
@@ -40,9 +42,14 @@ public class HttpViewHandler extends AbstractViewHandler {
public void init(ServletContext context) throws ViewHandlerException {
}
+ @Override
+ public Map<String, Object> prepareViewContext(HttpServletRequest request,
HttpServletResponse response, ConfigXMLReader.ViewMap viewMap) {
+ return Map.of();
+ }
+
@Override
public void render(String name, String page, String info, String
contentType, String encoding, HttpServletRequest request, HttpServletResponse
- response) throws ViewHandlerException {
+ response, Map<String, Object> context) throws ViewHandlerException
{
// some containers call filters on EVERY request, even forwarded ones,
// so let it know that it came from the control servlet
diff --git
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/JspViewHandler.java
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/JspViewHandler.java
index 23c04aa0e4..3112f34dbd 100644
---
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/JspViewHandler.java
+++
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/JspViewHandler.java
@@ -20,6 +20,7 @@ package org.apache.ofbiz.webapp.view;
import java.io.IOException;
+import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
@@ -29,6 +30,7 @@ import javax.servlet.jsp.JspException;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.UtilValidate;
+import org.apache.ofbiz.webapp.control.ConfigXMLReader;
import org.apache.ofbiz.webapp.control.ControlFilter;
/**
@@ -37,16 +39,21 @@ import org.apache.ofbiz.webapp.control.ControlFilter;
public class JspViewHandler extends AbstractViewHandler {
private static final String MODULE = JspViewHandler.class.getName();
- private ServletContext context;
+ private ServletContext servletContext;
@Override
- public void init(ServletContext context) throws ViewHandlerException {
- this.context = context;
+ public void init(ServletContext servletContext) throws
ViewHandlerException {
+ this.servletContext = servletContext;
+ }
+
+ @Override
+ public Map<String, Object> prepareViewContext(HttpServletRequest request,
HttpServletResponse response, ConfigXMLReader.ViewMap viewMap) {
+ return Map.of();
}
@Override
public void render(String name, String page, String contentType, String
encoding, String info, HttpServletRequest request, HttpServletResponse
- response) throws ViewHandlerException {
+ response, Map<String, Object> context) throws ViewHandlerException
{
// some containers call filters on EVERY request, even forwarded ones,
// so let it know that it came from the control servlet
@@ -66,10 +73,10 @@ public class JspViewHandler extends AbstractViewHandler {
if (rd == null) {
Debug.logInfo("HttpServletRequest.getRequestDispatcher() failed;
trying ServletContext", MODULE);
- rd = context.getRequestDispatcher(page);
+ rd = this.servletContext.getRequestDispatcher(page);
if (rd == null) {
Debug.logInfo("ServletContext.getRequestDispatcher() failed;
trying ServletContext.getNamedDispatcher(\"jsp\")", MODULE);
- rd = context.getNamedDispatcher("jsp");
+ rd = this.servletContext.getNamedDispatcher("jsp");
if (rd == null) {
throw new ViewHandlerException("Source returned a null
dispatcher (" + page + ")");
}
diff --git
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/ViewHandler.java
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/ViewHandler.java
index 6df8ec7b38..6c7591b096 100644
---
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/ViewHandler.java
+++
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/view/ViewHandler.java
@@ -18,9 +18,11 @@
*******************************************************************************/
package org.apache.ofbiz.webapp.view;
+import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.ofbiz.webapp.control.ConfigXMLReader;
/**
* ViewHandler - View Handler Interface
@@ -55,8 +57,18 @@ public interface ViewHandler {
* @param info An info string attached to this view
* @param request The HttpServletRequest object used when requesting this
page.
* @param response The HttpServletResponse object to be used to present
the page.
+ * @param context The context prepare by the handler to run
* @throws ViewHandlerException
*/
void render(String name, String page, String info, String contentType,
String encoding, HttpServletRequest request,
- HttpServletResponse response) throws ViewHandlerException;
+ HttpServletResponse response, Map<String, Object> context)
throws ViewHandlerException;
+
+ /**
+ * Before call the render, this function have to purpose to analyse,
secure and prepare the context
+ * @param request
+ * @param response
+ * @param viewMap
+ * @return
+ */
+ Map<String, Object> prepareViewContext(HttpServletRequest request,
HttpServletResponse response, ConfigXMLReader.ViewMap viewMap);
}
diff --git
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/ScreenRenderer.java
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/ScreenRenderer.java
index 24174f7f24..26d3334545 100644
---
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/ScreenRenderer.java
+++
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/ScreenRenderer.java
@@ -49,6 +49,7 @@ import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericEntity;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.util.EntityUtilProperties;
+import org.apache.ofbiz.security.SecuredFreemarker;
import org.apache.ofbiz.security.Security;
import org.apache.ofbiz.service.DispatchContext;
import org.apache.ofbiz.service.GenericServiceException;
@@ -219,12 +220,13 @@ public class ScreenRenderer {
* @param response
* @param servletContext
*/
- public void populateContextForRequest(HttpServletRequest request,
HttpServletResponse response, ServletContext servletContext) {
- populateContextForRequest(context, this, request, response,
servletContext);
+ public void populateContextForRequest(HttpServletRequest request,
HttpServletResponse response,
+ ServletContext servletContext,
boolean secureParameters) {
+ populateContextForRequest(context, this, request, response,
servletContext, secureParameters);
}
public static void populateContextForRequest(MapStack<String> context,
ScreenRenderer screens, HttpServletRequest request,
- HttpServletResponse response,
ServletContext servletContext) {
+ HttpServletResponse response,
ServletContext servletContext, boolean secureParameters) {
HttpSession session = request.getSession();
// attribute names to skip for session and application attributes;
these are all handled as special cases,
@@ -232,6 +234,9 @@ public class ScreenRenderer {
Set<String> attrNamesToSkip = UtilMisc.toSet("delegator",
"dispatcher", "security", "webSiteId",
"org.apache.catalina.jsp_classpath");
Map<String, Object> parameterMap = UtilHttp.getCombinedMap(request,
attrNamesToSkip);
+ if (secureParameters) {
+ parameterMap =
SecuredFreemarker.sanitizeParameterMap(parameterMap);
+ }
GenericValue userLogin = (GenericValue)
session.getAttribute("userLogin");
@@ -288,7 +293,7 @@ public class ScreenRenderer {
context.put("requestAttributes", new HttpRequestHashModel(request,
FreeMarkerWorker.getDefaultOfbizWrapper()));
TaglibFactory jspTaglibs = new TaglibFactory(servletContext);
context.put("JspTaglibs", jspTaglibs);
- context.put("requestParameters", UtilHttp.getParameterMap(request));
+ context.put("requestParameters",
SecuredFreemarker.sanitizeParameterMap(UtilHttp.getParameterMap(request)));
ServletContextHashModel ftlServletContext = (ServletContextHashModel)
request.getAttribute("ftlServletContext");
context.put("Application", ftlServletContext);
diff --git
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/fo/ScreenFopViewHandler.java
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/fo/ScreenFopViewHandler.java
index 8185738853..e2aac75248 100644
---
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/fo/ScreenFopViewHandler.java
+++
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/fo/ScreenFopViewHandler.java
@@ -25,6 +25,7 @@ import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
+import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -39,8 +40,11 @@ import org.apache.fop.render.pdf.PDFEncryptionOption;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.GeneralException;
import org.apache.ofbiz.base.util.UtilCodec;
+import org.apache.ofbiz.base.util.UtilGenerics;
import org.apache.ofbiz.base.util.UtilHttp;
import org.apache.ofbiz.base.util.UtilValidate;
+import org.apache.ofbiz.base.util.collections.MapStack;
+import org.apache.ofbiz.webapp.control.ConfigXMLReader;
import org.apache.ofbiz.webapp.view.AbstractViewHandler;
import org.apache.ofbiz.webapp.view.ApacheFopWorker;
import org.apache.ofbiz.webapp.view.ViewHandlerException;
@@ -72,14 +76,21 @@ public class ScreenFopViewHandler extends
AbstractViewHandler {
this.servletContext = context;
}
+
+ @Override
+ public Map<String, Object> prepareViewContext(HttpServletRequest request,
HttpServletResponse response, ConfigXMLReader.ViewMap viewMap) {
+ MapStack<String> context = MapStack.create();
+ ScreenRenderer.populateContextForRequest(context, null, request,
response, servletContext, viewMap.isSecureContext());
+ return context;
+ }
+
/**
- * @see org.apache.ofbiz.webapp.view.ViewHandler#render(java.lang.String,
java.lang.String, java.lang.String, java.lang.String, java.lang.String,
- * javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse)
+ * @see org.apache.ofbiz.webapp.view.ViewHandler#render(String, String,
String, String, String, HttpServletRequest, HttpServletResponse, Map)
*/
@SuppressWarnings("unchecked")
@Override
public void render(String name, String page, String info, String
contentType, String encoding, HttpServletRequest request,
- HttpServletResponse response) throws
ViewHandlerException {
+ HttpServletResponse response, Map<String, Object>
context) throws ViewHandlerException {
VisualTheme visualTheme = UtilHttp.getVisualTheme(request);
ModelTheme modelTheme = visualTheme.getModelTheme();
@@ -92,15 +103,14 @@ public class ScreenFopViewHandler extends
AbstractViewHandler {
// TODO: uncomment these lines when the renderers are implemented
//TreeStringRenderer treeStringRenderer = new
MacroTreeRenderer(modelTheme.getTreeRendererLocation(getName()), writer);
//MenuStringRenderer menuStringRenderer = new
MacroMenuRenderer(modelTheme.getMenuRendererLocation(getName()), writer);
- ScreenRenderer screens = new ScreenRenderer(writer, null,
screenStringRenderer);
- screens.populateContextForRequest(request, response,
servletContext);
+ ScreenRenderer screens = new ScreenRenderer(writer,
UtilGenerics.cast(context), screenStringRenderer);
// this is the object used to render forms from their definitions
screens.getContext().put("formStringRenderer", formStringRenderer);
screens.getContext().put("simpleEncoder",
UtilCodec.getEncoder(modelTheme.getEncoder(getName())));
screens.render(page);
} catch (IOException | GeneralException | SAXException |
ParserConfigurationException | TemplateException e) {
- renderError("Problems with the response writer/output stream", e,
"[Not Yet Rendered]", request, response);
+ renderError("Problems with the response writer/output stream", e,
"[Not Yet Rendered]", request, response, context);
return;
}
@@ -118,21 +128,21 @@ public class ScreenFopViewHandler extends
AbstractViewHandler {
}
// get encryption related parameters
FOUserAgent foUserAgent = null;
- String userPassword = request.getParameter("userPassword");
- String ownerPassword = request.getParameter("ownerPassword");
- boolean allowPrint =
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("allowPrint"))
- ? ApacheFopWorker.getAllowPrintDefault() :
request.getParameter("allowPrint"));
- boolean allowCopyContent =
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("allowCopyContent"))
- ? ApacheFopWorker.getAllowCopyContentDefault() :
request.getParameter("allowCopyContent"));
- boolean allowEditContent =
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("allowEditContent"))
- ? ApacheFopWorker.getAllowEditContentDefault() :
request.getParameter("allowEditContent"));
- boolean allowEditAnnotations =
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("allowEditAnnotations"))
- ? ApacheFopWorker.getAllowEditAnnotationsDefault() :
request.getParameter("allowEditAnnotations"));
+ String userPassword = (String) context.get("userPassword");
+ String ownerPassword = (String) context.get("ownerPassword");
+ boolean allowPrint =
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("allowPrint"))
+ ? ApacheFopWorker.getAllowPrintDefault() : (String)
context.get("allowPrint"));
+ boolean allowCopyContent =
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("allowCopyContent"))
+ ? ApacheFopWorker.getAllowCopyContentDefault() : (String)
context.get("allowCopyContent"));
+ boolean allowEditContent =
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("allowEditContent"))
+ ? ApacheFopWorker.getAllowEditContentDefault() : (String)
context.get("allowEditContent"));
+ boolean allowEditAnnotations =
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("allowEditAnnotations"))
+ ? ApacheFopWorker.getAllowEditAnnotationsDefault() : (String)
context.get("allowEditAnnotations"));
if (UtilValidate.isNotEmpty(userPassword) ||
UtilValidate.isNotEmpty(ownerPassword) || !allowPrint || !allowCopyContent ||
allowEditContent
|| !allowEditAnnotations) {
int encryptionLength = 128;
try {
- encryptionLength =
Integer.parseInt(request.getParameter("encryption-length"));
+ encryptionLength = Integer.parseInt((String)
context.get("encryption-length"));
} catch (NumberFormatException e) {
try {
encryptionLength =
Integer.parseInt(ApacheFopWorker.getEncryptionLengthDefault());
@@ -141,16 +151,16 @@ public class ScreenFopViewHandler extends
AbstractViewHandler {
}
}
- boolean encryptMetadata =
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("encrypt-metadata"))
- ? ApacheFopWorker.getEncryptMetadataDefault() :
request.getParameter("encrypt-metadata"));
- boolean allowFillInForms =
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("allowFillInForms"))
- ? ApacheFopWorker.getAllowFillInFormsDefault() :
request.getParameter("allowFillInForms"));
- boolean allowAccessContent =
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("allowAccessContent"))
- ? ApacheFopWorker.getAllowAccessContentDefault() :
request.getParameter("allowAccessContent"));
- boolean allowAssembleDocument =
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("allowAssembleDocument"))
- ? ApacheFopWorker.getAllowAssembleDocumentDefault() :
request.getParameter("allowAssembleDocument"));
- boolean allowPrintHq =
Boolean.parseBoolean(UtilValidate.isEmpty(request.getParameter("allowPrintHq"))
- ? ApacheFopWorker.getAllowPrintHqDefault() :
request.getParameter("allowPrintHq"));
+ boolean encryptMetadata =
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("encrypt-metadata"))
+ ? ApacheFopWorker.getEncryptMetadataDefault() : (String)
context.get("encrypt-metadata"));
+ boolean allowFillInForms =
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("allowFillInForms"))
+ ? ApacheFopWorker.getAllowFillInFormsDefault() : (String)
context.get("allowFillInForms"));
+ boolean allowAccessContent =
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("allowAccessContent"))
+ ? ApacheFopWorker.getAllowAccessContentDefault() :
(String) context.get("allowAccessContent"));
+ boolean allowAssembleDocument =
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("allowAssembleDocument"))
+ ? ApacheFopWorker.getAllowAssembleDocumentDefault() :
(String) context.get("allowAssembleDocument"));
+ boolean allowPrintHq =
Boolean.parseBoolean(UtilValidate.isEmpty(context.get("allowPrintHq"))
+ ? ApacheFopWorker.getAllowPrintHqDefault() : (String)
context.get("allowPrintHq"));
FopFactory fopFactory = ApacheFopWorker.getFactoryInstance();
foUserAgent = fopFactory.newFOUserAgent();
PDFEncryptionParams pdfEncryptionParams = new
PDFEncryptionParams(userPassword, ownerPassword, allowPrint, allowCopyContent,
@@ -179,7 +189,7 @@ public class ScreenFopViewHandler extends
AbstractViewHandler {
Fop fop = ApacheFopWorker.createFopInstance(out, contentType,
foUserAgent);
ApacheFopWorker.transform(src, null, fop);
} catch (Exception e) {
- renderError("Unable to transform FO file", e, screenOutString,
request, response);
+ renderError("Unable to transform FO file", e, screenOutString,
request, response, context);
return;
}
// set the content type and length
@@ -191,7 +201,7 @@ public class ScreenFopViewHandler extends
AbstractViewHandler {
out.writeTo(response.getOutputStream());
response.getOutputStream().flush();
} catch (IOException e) {
- renderError("Unable to write to OutputStream", e, screenOutString,
request, response);
+ renderError("Unable to write to OutputStream", e, screenOutString,
request, response, context);
}
}
@@ -204,7 +214,9 @@ public class ScreenFopViewHandler extends
AbstractViewHandler {
* @param response the response
* @throws ViewHandlerException the view handler exception
*/
- protected void renderError(String msg, Exception e, String
screenOutString, HttpServletRequest request, HttpServletResponse response)
+ protected void renderError(String msg, Exception e, String screenOutString,
+ HttpServletRequest request, HttpServletResponse
response,
+ Map<String, Object> context)
throws ViewHandlerException {
Debug.logError(msg + ": " + e + "; Screen XSL:FO text was:\n" +
screenOutString, MODULE);
try {
@@ -214,8 +226,7 @@ public class ScreenFopViewHandler extends
AbstractViewHandler {
ScreenStringRenderer screenStringRenderer = new
MacroScreenRenderer(modelTheme.getType("screen"),
modelTheme.getScreenRendererLocation("screen"));
- ScreenRenderer screens = new ScreenRenderer(writer, null,
screenStringRenderer);
- screens.populateContextForRequest(request, response,
servletContext);
+ ScreenRenderer screens = new ScreenRenderer(writer,
UtilGenerics.cast(context), screenStringRenderer);
screens.getContext().put("errorMessage", msg + ": " + e);
screens.render(DEFAULT_ERROR_TEMPLATE);
response.setContentType("text/html");
diff --git
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroScreenViewHandler.java
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroScreenViewHandler.java
index 4365a7bbaf..19350f6938 100644
---
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroScreenViewHandler.java
+++
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroScreenViewHandler.java
@@ -33,6 +33,7 @@ import org.apache.ofbiz.base.util.UtilCodec;
import org.apache.ofbiz.base.util.UtilHttp;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.base.util.collections.MapStack;
+import org.apache.ofbiz.webapp.control.ConfigXMLReader;
import org.apache.ofbiz.webapp.view.AbstractViewHandler;
import org.apache.ofbiz.webapp.view.ViewHandlerException;
import org.apache.ofbiz.widget.model.ModelTheme;
@@ -83,9 +84,17 @@ public class MacroScreenViewHandler extends
AbstractViewHandler {
return screenStringRenderer;
}
+
+ @Override
+ public Map<String, Object> prepareViewContext(HttpServletRequest request,
HttpServletResponse response, ConfigXMLReader.ViewMap viewMap) {
+ MapStack<String> context = MapStack.create();
+ ScreenRenderer.populateContextForRequest(context, null, request,
response, servletContext, viewMap.isSecureContext());
+ return context;
+ }
+
@Override
public void render(String name, String page, String info, String
contentType, String encoding, HttpServletRequest request,
- HttpServletResponse response) throws
ViewHandlerException {
+ HttpServletResponse response, Map<String, Object>
context) throws ViewHandlerException {
try {
Writer writer = response.getWriter();
VisualTheme visualTheme = UtilHttp.getVisualTheme(request);
@@ -106,10 +115,8 @@ public class MacroScreenViewHandler extends
AbstractViewHandler {
// to speed up output.
writer = new StandardCompress().getWriter(writer, null);
}
- MapStack<String> context = MapStack.create();
- ScreenRenderer.populateContextForRequest(context, null, request,
response, servletContext);
ScreenStringRenderer screenStringRenderer = loadRenderers(request,
response, context, writer);
- ScreenRenderer screens = new ScreenRenderer(writer, context,
screenStringRenderer);
+ ScreenRenderer screens = new ScreenRenderer(writer,
MapStack.create(context), screenStringRenderer);
context.put("screens", screens);
context.put("simpleEncoder",
UtilCodec.getEncoder(visualTheme.getModelTheme().getEncoder(getName())));
screenStringRenderer.renderBegin(writer, context);