mirror of https://github.com/apache/nifi.git
NIFI-494:
- Escaping parameters as appropriate. - Additional error handling.
This commit is contained in:
parent
2154b822bf
commit
eb023e57b2
|
@ -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.nifi.util;
|
||||
|
||||
public class EscapeUtils {
|
||||
|
||||
/**
|
||||
* Escapes the specified html by replacing &, <, >, ", ', /
|
||||
* with their corresponding html entity. If html is null, null is returned.
|
||||
*
|
||||
* @param html
|
||||
* @return
|
||||
*/
|
||||
public static String escapeHtml(String html) {
|
||||
if (html == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
html = html.replace("&", "&");
|
||||
html = html.replace("<", "<");
|
||||
html = html.replace(">", ">");
|
||||
html = html.replace("\"", """);
|
||||
html = html.replace("'", "'");
|
||||
html = html.replace("/", "/");
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
|
@ -121,8 +121,14 @@ public class StandardNiFiContentAccess implements ContentAccess {
|
|||
final String rawDirection = StringUtils.substringAfterLast(eventDetails, "/content/");
|
||||
|
||||
// get the content type
|
||||
final Long eventId = Long.parseLong(rawEventId);
|
||||
final ContentDirection direction = ContentDirection.valueOf(rawDirection.toUpperCase());
|
||||
final Long eventId;
|
||||
final ContentDirection direction;
|
||||
try {
|
||||
eventId = Long.parseLong(rawEventId);
|
||||
direction = ContentDirection.valueOf(rawDirection.toUpperCase());
|
||||
} catch (final IllegalArgumentException iae) {
|
||||
throw new IllegalArgumentException("The specified data reference URI is not valid.");
|
||||
}
|
||||
return serviceFacade.getContent(eventId, request.getDataUri(), direction);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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.nifi.web.api.config;
|
||||
|
||||
import com.sun.jersey.api.NotFoundException;
|
||||
import com.sun.jersey.api.Responses;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.ext.ExceptionMapper;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
import org.apache.nifi.util.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Maps not found exceptions into client responses.
|
||||
*/
|
||||
@Provider
|
||||
public class NotFoundExceptionMapper implements ExceptionMapper<NotFoundException> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(NotFoundExceptionMapper.class);
|
||||
|
||||
@Override
|
||||
public Response toResponse(NotFoundException exception) {
|
||||
// log the error
|
||||
logger.info(String.format("%s. Returning %s response.", exception, Response.Status.NOT_FOUND));
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(StringUtils.EMPTY, exception);
|
||||
}
|
||||
|
||||
return Responses.notFound().entity("The specified resource could not be found.").type("text/plain").build();
|
||||
}
|
||||
|
||||
}
|
|
@ -270,6 +270,7 @@
|
|||
<bean class="org.apache.nifi.web.api.config.NodeReconnectionExceptionMapper" scope="singleton"/>
|
||||
<bean class="org.apache.nifi.web.api.config.PrimaryRoleAssignmentExceptionMapper" scope="singleton"/>
|
||||
<bean class="org.apache.nifi.web.api.config.ResourceNotFoundExceptionMapper" scope="singleton"/>
|
||||
<bean class="org.apache.nifi.web.api.config.NotFoundExceptionMapper" scope="singleton"/>
|
||||
<bean class="org.apache.nifi.web.api.config.UnknownNodeExceptionMapper" scope="singleton"/>
|
||||
<bean class="org.apache.nifi.web.api.config.ValidationExceptionMapper" scope="singleton"/>
|
||||
<bean class="org.apache.nifi.web.api.config.WebApplicationExceptionMapper" scope="singleton"/>
|
||||
|
|
|
@ -68,10 +68,21 @@ public class ContentViewerController extends HttpServlet {
|
|||
final ServletContext servletContext = request.getServletContext();
|
||||
final ContentAccess contentAccess = (ContentAccess) servletContext.getAttribute("nifi-content-access");
|
||||
|
||||
final ContentRequestContext contentRequest = getContentRequest(request);
|
||||
if (contentRequest.getDataUri() == null) {
|
||||
request.setAttribute("title", "Error");
|
||||
request.setAttribute("messages", "The data reference must be specified.");
|
||||
|
||||
// forward to the error page
|
||||
final ServletContext viewerContext = servletContext.getContext("/nifi");
|
||||
viewerContext.getRequestDispatcher("/message").forward(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
// get the content
|
||||
final DownloadableContent downloadableContent;
|
||||
try {
|
||||
downloadableContent = contentAccess.getContent(getContentRequest(request));
|
||||
downloadableContent = contentAccess.getContent(contentRequest);
|
||||
} catch (final ResourceNotFoundException rnfe) {
|
||||
request.setAttribute("title", "Error");
|
||||
request.setAttribute("messages", "Unable to find the specified content");
|
||||
|
@ -138,9 +149,6 @@ public class ContentViewerController extends HttpServlet {
|
|||
final String mimeType = mediatype.toString();
|
||||
|
||||
// add attributes needed for the header
|
||||
final StringBuffer requestUrl = request.getRequestURL();
|
||||
request.setAttribute("requestUrl", requestUrl.toString());
|
||||
request.setAttribute("dataRef", request.getParameter("ref"));
|
||||
request.setAttribute("filename", downloadableContent.getFilename());
|
||||
request.setAttribute("contentType", mimeType);
|
||||
|
||||
|
@ -148,8 +156,6 @@ public class ContentViewerController extends HttpServlet {
|
|||
request.getRequestDispatcher("/WEB-INF/jsp/header.jsp").include(request, response);
|
||||
|
||||
// remove the attributes needed for the header
|
||||
request.removeAttribute("requestUrl");
|
||||
request.removeAttribute("dataRef");
|
||||
request.removeAttribute("filename");
|
||||
request.removeAttribute("contentType");
|
||||
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
<script type="text/javascript">
|
||||
var $$ = $.noConflict(true);
|
||||
$$(document).ready(function () {
|
||||
var url = '${requestUrl}';
|
||||
var ref = '${param.ref}';
|
||||
var url = $$('#requestUrl').text();
|
||||
var ref = $$('#ref').text();
|
||||
|
||||
// create the parameters
|
||||
var params = {
|
||||
|
@ -40,14 +40,14 @@
|
|||
};
|
||||
|
||||
// include the cluster node if appropriate
|
||||
var clusterNodeId = '${param.clusterNodeId}';
|
||||
if (clusterNodeId !== null && clusterNodeId !== '') {
|
||||
var clusterNodeId = $$('#clusterNodeId').text();
|
||||
if (clusterNodeId !== '') {
|
||||
params['clusterNodeId'] = clusterNodeId;
|
||||
}
|
||||
|
||||
// determine the appropriate mode to select initially
|
||||
var initialMode = '${param.mode}';
|
||||
if (initialMode === null && initialMode === '') {
|
||||
var initialMode = $$('#mode').text();
|
||||
if (initialMode === '') {
|
||||
initialMode = 'Original';
|
||||
}
|
||||
|
||||
|
@ -85,8 +85,12 @@
|
|||
</script>
|
||||
</head>
|
||||
<body class="message-pane">
|
||||
<span id="ref" class="hidden"><%= org.apache.nifi.util.EscapeUtils.escapeHtml(request.getParameter("ref")) %></span>
|
||||
<span id="clusterNodeId" class="hidden"><%= request.getParameter("clusterNodeId") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getParameter("clusterNodeId")) %></span>
|
||||
<span id="mode" class="hidden"><%= request.getParameter("mode") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getParameter("mode")) %></span>
|
||||
<span id="requestUrl" class="hidden"><%= org.apache.nifi.util.EscapeUtils.escapeHtml(request.getRequestURL().toString()) %></span>
|
||||
<div id="view-as-label">View as</div>
|
||||
<div id="view-as" class="pointer button-normal"></div>
|
||||
<div id="content-filename"><span class="content-label">filename</span>${filename}</div>
|
||||
<div id="content-type"><span class="content-label">content type</span>${contentType}</div>
|
||||
<div id="content-filename"><span class="content-label">filename</span><%= request.getAttribute("filename") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("filename").toString()) %></div>
|
||||
<div id="content-type"><span class="content-label">content type</span><%= request.getAttribute("contentType") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("contentType").toString()) %></div>
|
||||
<div class="message-pane-message-box">
|
|
@ -148,7 +148,7 @@ $(document).ready(function () {
|
|||
|
||||
$("table", div).addClass("hexviewerwindow_table");
|
||||
$("table", div).append("<tr></tr>").addClass("hexviewerwindow");
|
||||
$("table tr:last", div).append("<td>" + (decimal_offset ? ("00000000"+offset).slice(-8) : "0x" + dec_to_hex8(offset)) + "</td>");
|
||||
$("table tr:last", div).append("<td>" + escapeHtml((decimal_offset ? ("00000000"+offset).slice(-8) : "0x" + dec_to_hex8(offset))) + "</td>");
|
||||
$("table tr td:last", div).addClass("hexviewerwindow_offset");
|
||||
|
||||
var runlen = 0;
|
||||
|
@ -162,7 +162,7 @@ $(document).ready(function () {
|
|||
num += dec2_to_hex(line_data.charCodeAt(i+j));
|
||||
}
|
||||
|
||||
$("table tr:last", div).append("<td>" + (hide_0x ? "" : "0x") + num + "</td>");
|
||||
$("table tr:last", div).append("<td>" + escapeHtml((hide_0x ? "" : "0x") + num) + "</td>");
|
||||
|
||||
apply_highlights(offset+i);
|
||||
}
|
||||
|
|
|
@ -26,12 +26,18 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-nar-utils</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-utils</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet.jsp</groupId>
|
||||
<artifactId>javax.servlet.jsp-api</artifactId>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<body id="documentation-body">
|
||||
<div id="banner-header" class="main-banner-header"></div>
|
||||
<div id="banner-footer" class="main-banner-footer"></div>
|
||||
<span id="initial-selection" style="display: none;">${param.select}</span>
|
||||
<span id="initial-selection" style="display: none;"><%= request.getParameter("select") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getParameter("select")) %></span>
|
||||
<div id="documentation-header" class="documentation-header">
|
||||
<div id="nf-title">NiFi Documentation</div>
|
||||
<div id="nf-version"></div>
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* global top */
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
var isUndefined = function (obj) {
|
||||
|
@ -139,7 +142,7 @@ $(document).ready(function () {
|
|||
if (isDefinedAndNotNull(response.banners)) {
|
||||
if (isDefinedAndNotNull(response.banners.headerText) && response.banners.headerText !== '') {
|
||||
// update the header text
|
||||
var bannerHeader = $('#banner-header').html(response.banners.headerText).show();
|
||||
var bannerHeader = $('#banner-header').text(response.banners.headerText).show();
|
||||
|
||||
// show the banner
|
||||
var updateTop = function (elementId) {
|
||||
|
@ -155,7 +158,7 @@ $(document).ready(function () {
|
|||
|
||||
if (isDefinedAndNotNull(response.banners.footerText) && response.banners.footerText !== '') {
|
||||
// update the footer text and show it
|
||||
var bannerFooter = $('#banner-footer').html(response.banners.footerText).show();
|
||||
var bannerFooter = $('#banner-footer').text(response.banners.footerText).show();
|
||||
|
||||
var updateBottom = function (elementId) {
|
||||
var element = $('#' + elementId);
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
<packageRoot>org.apache.nifi.web.jsp</packageRoot>
|
||||
<keepSources>true</keepSources>
|
||||
<verbose>true</verbose>
|
||||
<useProvidedScope>true</useProvidedScope>
|
||||
<excludes>
|
||||
**/canvas.jsp,
|
||||
**/summary.jsp,
|
||||
|
@ -619,6 +620,11 @@
|
|||
<artifactId>commons-io</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-utils</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>${title}</title>
|
||||
<title><%= request.getAttribute("title") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("title").toString()) %></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<link rel="shortcut icon" href="images/nifi16.ico"/>
|
||||
<link href="/nifi/css/message-pane.css" rel="stylesheet" type="text/css" />
|
||||
|
@ -27,8 +27,8 @@
|
|||
|
||||
<body class="message-pane">
|
||||
<div class="message-pane-message-box">
|
||||
<p class="message-pane-title">${title}</p>
|
||||
<p class="message-pane-content">${messages}</p>
|
||||
<p class="message-pane-title"><%= request.getAttribute("title") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("title").toString()) %></p>
|
||||
<p class="message-pane-content"><%= request.getAttribute("messages") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("messages").toString()) %></p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -28,6 +28,11 @@
|
|||
<artifactId>commons-lang3</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-utils</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
|
|
|
@ -20,13 +20,16 @@
|
|||
<script type="text/javascript" src="../nifi/js/codemirror/lib/codemirror-compressed.js"></script>
|
||||
<script type="text/javascript" src="../nifi/js/jquery/jquery-2.1.1.min.js"></script>
|
||||
|
||||
<textarea id="codemirror-content">${content}</textarea>
|
||||
<textarea id="codemirror-content"><%= request.getAttribute("content") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("content").toString()) %></textarea>
|
||||
<span id="codemirror-mode" style="display: none;"><%= org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("mode").toString()) %></span>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
var mode = $('#codemirror-mode').text();
|
||||
|
||||
var field = document.getElementById('codemirror-content');
|
||||
var editor = CodeMirror.fromTextArea(field, {
|
||||
mode: '${mode}',
|
||||
mode: mode,
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
foldGutter: true,
|
||||
|
|
|
@ -33,6 +33,11 @@
|
|||
<artifactId>nifi-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-utils</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-custom-ui-utilities</artifactId>
|
||||
|
|
|
@ -59,10 +59,10 @@
|
|||
<title>Update Attribute</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="attribute-updater-processor-id" class="hidden">${param.id}</div>
|
||||
<div id="attribute-updater-client-id" class="hidden">${param.clientId}</div>
|
||||
<div id="attribute-updater-revision" class="hidden">${param.revision}</div>
|
||||
<div id="attribute-updater-editable" class="hidden">${param.editable}</div>
|
||||
<div id="attribute-updater-processor-id" class="hidden"><%= request.getParameter("id") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getParameter("id")) %></div>
|
||||
<div id="attribute-updater-client-id" class="hidden"><%= request.getParameter("clientId") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getParameter("clientId")) %></div>
|
||||
<div id="attribute-updater-revision" class="hidden"><%= request.getParameter("revision") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getParameter("revision")) %></div>
|
||||
<div id="attribute-updater-editable" class="hidden"><%= request.getParameter("editable") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getParameter("editable")) %></div>
|
||||
<div id="update-attributes-content">
|
||||
<div id="rule-list-panel">
|
||||
<div id="flowfile-policy-container">
|
||||
|
|
Loading…
Reference in New Issue