/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2017 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.platform.web.servlet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.pentaho.platform.api.engine.IPentahoSession;
import org.pentaho.platform.api.engine.IAuthorizationPolicy;
import org.pentaho.platform.engine.core.system.PentahoSessionHolder;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import org.pentaho.platform.util.UUIDUtil;
import org.pentaho.platform.web.servlet.messages.Messages;
import org.pentaho.reporting.libraries.base.util.StringUtils;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class UploadFileServlet extends HttpServlet implements Servlet {
private static final long serialVersionUID = 8305367618713715640L;
protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
try {
IPentahoSession session = PentahoSessionHolder.getSession();
if ( !hasManageDataAccessPermission( session ) ) {
response.sendError( 403, Messages.getInstance().getErrorString( "UploadFileServlet.ERROR_0009_UNAUTHORIZED" ) );
return;
}
UploadFileUtils utils = new UploadFileUtils( session );
response.setContentType( "text/plain" ); //$NON-NLS-1$
// Note - request.getParameter doesn't work on multi-part file data. But just in case,
// we get the standardRequestParamaters as well as the parameter map we create from the
// multi-part form data.
Map<String, String[]> standardRequestParameters = request.getParameterMap();
Map<String, FileItem> parsedMultiPartRequestParameters = this.getParsedRequestParameters( request, session );
FileItem uploadItem = parsedMultiPartRequestParameters.get( "uploadFormElement" ); //$NON-NLS-1$
if ( uploadItem == null ) {
String error = Messages.getInstance().getErrorString( "UploadFileServlet.ERROR_0001_NO_FILE_TO_UPLOAD" ); //$NON-NLS-1$
response.getWriter().write( error );
return;
}
String unzip = getRequestParameter( standardRequestParameters, parsedMultiPartRequestParameters, "unzip" ); //$NON-NLS-1$
String temporary =
getRequestParameter( standardRequestParameters, parsedMultiPartRequestParameters, "mark_temporary" ); //$NON-NLS-1$
String fileName = getRequestParameter( standardRequestParameters, parsedMultiPartRequestParameters, "file_name" ); //$NON-NLS-1$
if ( StringUtils.isEmpty( fileName ) ) {
fileName = UUIDUtil.getUUID().toString();
}
boolean isTemporary = false;
if ( temporary != null ) {
isTemporary = Boolean.valueOf( temporary );
}
boolean shouldUnzip = false;
if ( unzip != null ) {
shouldUnzip = Boolean.valueOf( unzip );
}
utils.setShouldUnzip( shouldUnzip );
utils.setTemporary( isTemporary );
utils.setFileName( fileName );
utils.setWriter( response.getWriter() );
utils.setUploadedFileItem( uploadItem );
utils.process(); // Do nothing with success value - the output should already have been written to the servlet response.
} catch ( Exception e ) {
String error =
Messages.getInstance().getErrorString( "UploadFileServlet.ERROR_0005_UNKNOWN_ERROR",
e.getLocalizedMessage() ); //$NON-NLS-1
response.getWriter().write( error );
}
}
protected String getRequestParameter( Map<String, String[]> primary, Map<String, FileItem> secondary, String parameterName ) {
String rtn = getRequestParameter( primary, parameterName );
return ( rtn != null ) ? rtn : getRequestParameter( secondary, parameterName );
}
protected String getRequestParameter( Map<String, ?> requestParameters, String parameterName ) {
Object obj = requestParameters.get( parameterName );
if ( obj != null ) {
if ( obj instanceof FileItem ) {
return ( (FileItem) obj ).getString();
} else if ( obj instanceof String[] ) { // such is the case for request.getParameterMap() values
String[] a = (String[]) obj;
if ( a.length > 0 ) {
return a[0];
}
} else {
return obj.toString();
}
}
return null;
}
/**
* Parses the multi-part request to get all the parameters out.
*
* @param request
* @param session
* @return Map of the request parameters
*/
private Map<String, FileItem> getParsedRequestParameters( HttpServletRequest request, IPentahoSession session ) {
HashMap<String, FileItem> rtn = new HashMap<>();
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload( factory );
try {
List<FileItem> items = upload.parseRequest( request );
Iterator<FileItem> it = items.iterator();
while ( it.hasNext() ) {
FileItem item = it.next();
String fName = item.getFieldName();
rtn.put( fName, item );
}
} catch ( FileUploadException e ) {
return null;
}
return rtn;
}
/**
* Returns true if the current user has Manage Data Source Security. Otherwise returns false.
* @param session
* @return
*/
protected boolean hasManageDataAccessPermission( IPentahoSession session ) {
// If this breaks an OEM's plugin, provide a get-out-of-jail card with an entry in the pentaho.xml.
String override = PentahoSystem.getSystemSetting( "data-access-override", "false" );
Boolean rtnOverride = Boolean.valueOf( override );
if ( !rtnOverride ) {
IAuthorizationPolicy policy = PentahoSystem.get( IAuthorizationPolicy.class );
if ( policy != null ) {
return policy.isAllowed( "org.pentaho.platform.dataaccess.datasource.security.manage" );
} else {
return false;
}
} else {
return true; // Override the security policy with the entry in the pentaho.xml.
}
}
}