From 29ad090c29567ff1a4d3a2ec9b8ad0b5d80ee24d Mon Sep 17 00:00:00 2001 From: pdanner Date: Mon, 6 Dec 2010 16:34:52 +0000 Subject: git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@671 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../at/gv/egiz/pdfas/web/servlets/SignServlet.java | 656 +++++++++++++++++++++ 1 file changed, 656 insertions(+) create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignServlet.java (limited to 'pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignServlet.java') diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignServlet.java new file mode 100644 index 0000000..acd71b0 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignServlet.java @@ -0,0 +1,656 @@ +/** + * Copyright (c) 2006 by Know-Center, Graz, Austria + * + * This software is the confidential and proprietary information of Know-Center, + * Graz, Austria. You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Know-Center. + * + * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF + * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY + * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. + * + * $Id: Sign.java,v 1.7 2006/10/11 07:39:13 wprinz Exp $ + */ +package at.gv.egiz.pdfas.web.servlets; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +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.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.api.exceptions.PdfAsException; +import at.gv.egiz.pdfas.api.io.DataSource; +import at.gv.egiz.pdfas.api.io.TextBased; +import at.gv.egiz.pdfas.api.sign.pos.SignaturePositioning; +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.gv.egiz.pdfas.exceptions.ErrorCodeHelper; +import at.gv.egiz.pdfas.exceptions.external.ExternalErrorException; +import at.gv.egiz.pdfas.web.ExternAppInformation; +import at.gv.egiz.pdfas.web.FormFields; +import at.gv.egiz.pdfas.web.helper.ApiHelper; +import at.gv.egiz.pdfas.web.helper.SignServletHelper; +import at.gv.egiz.pdfas.web.helper.WebSettingsReader; +import at.gv.egiz.pdfas.web.helper.WebUtils; +import at.gv.egiz.pdfas.web.io.ByteArrayPdfDataSource; +import at.gv.egiz.pdfas.web.itext.IText; +import at.gv.egiz.pdfas.web.session.SessionAttributes; +import at.gv.egiz.pdfas.web.session.SignSessionInformation; +import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; +import at.knowcenter.wag.egov.egiz.exceptions.PlaceholderException; +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; + +import com.lowagie.text.DocumentException; + +/** + * This method is the sign servlet for the pdf-as web application. It takes get + * and post requests fill out jsp templates and give the user feedback about the + * results of the sign process + * + * @author wlackner + * @author wprinz + */ +public class SignServlet extends HttpServlet +{ + + /** + * SVUID. + */ + private static final long serialVersionUID = -4156938216903740438L; + + /** + * The log. + */ + private static Log log = LogFactory.getLog(SignServlet.class); + private static Log statLog = LogFactory.getLog("statistic"); + + protected void dispatch(HttpServletRequest request, HttpServletResponse response, String resource) throws ServletException, IOException + { + dispatch(request, response, resource, getServletContext()); + } + + protected static void dispatch(HttpServletRequest request, HttpServletResponse response, String resource, ServletContext context) throws ServletException, IOException + { + response.setContentType("text/html"); + response.setCharacterEncoding("UTF-8"); + + RequestDispatcher disp = context.getRequestDispatcher(resource); + disp.forward(request, response); + } + + // The sign servlet is used for processing the upload only. + // Authentication is deactivated. if required - make an own servlet. + // /** + // * @author modified by tknall + // */ + // public void doGet(HttpServletRequest request, HttpServletResponse response) + // throws ServletException, IOException + // { + // String authenticate = request.getHeader(AUTH); + // if (authenticate != null) + // { + // logger_.info("authenticate:" + authenticate); + // if (authenticate.indexOf(AUTH_BASIC) == 0) + // { + // authenticate = authenticate.substring(AUTH_BASIC.length() + 1); + // logger_.info("authenticate:" + authenticate); + // authenticate = new String(CodingHelper.decodeBase64(authenticate), + // "UTF-8"); + // logger_.info("authenticate:" + authenticate); + // + // String[] auth_value = authenticate.split(":"); + // String user_name = auth_value[0]; + // String user_password = auth_value[1]; + // logger_.info("username:" + user_name); + // // start modification tknall + // // logger_.info("password:" + user_password); + // logger_.info("password:XXXXXXXXXXXX"); + // // stop modification tknall + // + // HttpSession session = request.getSession(); + // session.setAttribute(SessionAttributes.ATTRIBUTE_USER_NAME, user_name); + // session.setAttribute(SessionAttributes.ATTRIBUTE_USER_PASSWORD, + // user_password); + // + // dispatch(request, response, "/jsp/signupload.jsp"); + // return; + // } + // // start modification tknall + // } else { + // String user_name = ""; + // String user_password = ""; + // logger_.info("authenticate:User has not been authenticated!"); + // logger_.info("username: UNKNOWN"); + // logger_.info("password: XXXXXXXXXXXX"); + // HttpSession session = request.getSession(); + // session.setAttribute("uname", user_name); + // session.setAttribute("upass", user_password); + // dispatch(request, response, "/jsp/signupload.jsp"); + // } + + // request.setAttribute("error", "Falsche Authentifikation"); + // request.setAttribute("cause", "Passwort oder Benutzername ist falsch"); + // dispatch(request, response, "/jsp/error.jsp"); + // // stop modification tknall + // } + + /** + * Processes the sign upload. + * + * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + UploadedData ud = null; + ExternAppInformation exappinf = null; +// TablePos pos = null; + SignaturePositioning sigpos = null; + + // for performance measurement + long startTime = 0; + if (statLog.isInfoEnabled()) { + startTime = System.currentTimeMillis(); + } + + + + // check if pdf-as has been called by external webapp + if (request.getParameter(FormFields.FIELD_PDF_URL) != null) + { + + String preview = (String) request.getParameter(FormFields.FIELD_PREVIEW); + String sig_type = (String) request.getParameter(FormFields.FIELD_SIGNATURE_TYPE); + String sig_app = (String) request.getParameter(FormFields.FIELD_CONNECTOR); + String sig_mode = (String) request.getParameter(FormFields.FIELD_MODE); + String filename = (String) request.getParameter(FormFields.FIELD_FILENAME); + String pdf_url = (String) request.getParameter(FormFields.FIELD_PDF_URL); + String pdf_id = (String) request.getParameter(FormFields.FIELD_PDF_ID); + String pdf_length = (String) request.getParameter(FormFields.FIELD_FILE_LENGTH); + String invoke_url = (String) request.getParameter(FormFields.FIELD_INVOKE_APP_URL); + String invoke_error_url = (String) request.getParameter(FormFields.FIELD_INVOKE_APP_ERROR_URL); + String session_id = (String) request.getParameter(FormFields.FIELD_SESSION_ID); + String sig_pos_y = (String) request.getParameter(FormFields.FIELD_SIGPOS_Y); + String sig_pos_p = (String) request.getParameter(FormFields.FIELD_SIGPOS_P); + + // added by tknall + if (sig_pos_y != null && sig_pos_p != null) { + try + { +// pos = new TablePos("y:" + sig_pos_y + ";p:" + sig_pos_p); + sigpos = new SignaturePositioning("y:" + sig_pos_y + ";p:" + sig_pos_p); + } + catch (PDFDocumentException e) + { + log.warn("Unable to create signature position object: " + e.getMessage(), e); + } + } else { + log.debug("No signature position provided."); + } + + // fixed by tknall: if we already have parameters "&" must be used instead of "?" + String paramSeparator = (pdf_url.indexOf("?") != -1) ? "&" : "?"; + String query = pdf_url + paramSeparator + FormFields.FIELD_PDF_ID + "=" + pdf_id; + + // wprinz: rem: this allocation is useless + // byte[] extern_pdf = new byte[Integer.parseInt(pdf_length)]; + URL source_url = new URL(query); + InputStream is = source_url.openStream(); + + // extern_pdf = toByteArray(is); + + // set UploadedData object... + UploadedData ud_extern = new UploadedData(); + + ud_extern.file_name = filename; + ud_extern.pdfDataSource = new ByteArrayPdfDataSource(IOUtils.toByteArray(is)); + + // ud_extern.pdf = extern_pdf; +// ud_extern.preview = preview.equalsIgnoreCase("true") ? true : false; + ud_extern.preview = "true".equalsIgnoreCase(preview); + ud_extern.sig_app = sig_app; + ud_extern.sig_mode = sig_mode; + ud_extern.sig_type = sig_type; + + ud = ud_extern; + + exappinf = new ExternAppInformation(invoke_url, pdf_id, session_id, invoke_error_url); + } + else + { + + try + { + + // tzefferer: modified + // UploadedData ud = retrieveUploadedDataFromRequest(request); + UploadedData ud_form = retrieveUploadedDataFromRequest(request); + ud = ud_form; + // end modify + + } + catch (Exception e) + { + log.error(e); + request.setAttribute("error", "signservlet.error"); + request.setAttribute("cause", "signservlet.cause"); + request.setAttribute("resourcebundle", Boolean.TRUE); + dispatch(request, response, "/jsp/error.jsp"); + return; + } + } + try + { + +// not needed, that is done in sign() +// ud.pdfDataSource = PdfAS.applyStrictMode(ud.pdfDataSource); + + SignSessionInformation si = new SignSessionInformation(); // SessionTable.generateSessionInformationObject(); + si.connector = ud.sig_app; + si.application = "sign"; + si.mode = ud.sig_mode; + si.pdfDataSource = ud.pdfDataSource; + si.type = ud.sig_type; + si.filename = formatFileName(ud.file_name); + si.download_inline = ud.download_inline; + + // added tzefferer: + si.exappinf = exappinf; + si.pos = sigpos; + // end add + + HttpSession session = request.getSession(); + log.info("Putting signature data into session " + session.getId()); + session.setAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION, si); + + // String user_name = (String) + // request.getSession().getAttribute(SessionAttributes.ATTRIBUTE_USER_NAME); + // String user_password = (String) + // request.getSession().getAttribute(SessionAttributes.ATTRIBUTE_USER_PASSWORD); + // si.user_name = user_name; + // si.user_password = user_password; + + SignServletHelper.prepareSign(ApiHelper.getPdfAsFromContext(getServletContext()), si); + + if (ud.preview) + { + String submit_url = response.encodeURL(request.getContextPath() + "/SignPreview"); +// String signature_data_url = response.encodeURL(WebUtils.addJSessionID(request.getContextPath() + "/RetrieveSignatureData", request)); + String signature_data_url = response.encodeURL(WebUtils.buildRetrieveSignatureDataURL(request, response)); + + request.setAttribute("submit_url", submit_url); + request.setAttribute("signature_data_url", signature_data_url); + if (si.mode.equals(FormFields.VALUE_MODE_TEXTUAL)){ + request.setAttribute("document_text", ((TextBased)si.sdi.getSignatureData()).getText()); + } + + dispatch(request, response, "/jsp/signpreview.jsp"); + + return; + } + + SignServletHelper.finishSign(si, request, response, getServletContext()); + + // for performance measurement + if (statLog.isInfoEnabled()) { + long endTime = System.currentTimeMillis(); +// String toReport = "SIGN;" + si.mode + ";" + si.filename + ";"+ fileSize + ";" + + String toReport = "SIGN;" + si.mode + ";" + si.connector + ";" + si.pdfDataSource.getLength() + ";" + (endTime - startTime); + + statLog.info(toReport); + } + } + catch (PresentableException e) + { + log.error(e.getMessage(), e); + prepareDispatchToErrorPage(e, request); + dispatch(request, response, "/jsp/error.jsp"); + } catch (Exception e) { + log.error(e.getMessage(), e); + PresentableException pe = new PresentableException(ErrorCode.UNKNOWN_ERROR, e); + prepareDispatchToErrorPage(pe, request); + dispatch(request, response, "/jsp/error.jsp"); + } + } + + // tzefferer:added + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + doPost(request, response); + } + // end add + + protected UploadedData retrieveUploadedDataFromRequest(HttpServletRequest request) throws ServletException, UnsupportedEncodingException, FileUploadException, PDFDocumentException + { + DiskFileItemFactory fif = new DiskFileItemFactory(); + fif.setRepository(WebSettingsReader.getTemporaryDirectory()); + ServletFileUpload sfu = new ServletFileUpload(fif); + + List items = sfu.parseRequest(request); + + FileItem preview_fi = null; + FileItem sig_type_fi = null; + FileItem sig_app_fi = null; + FileItem mode_fi = null; + FileItem file_upload_fi = null; + FileItem download_fi = null; + FileItem freeText = null; + FileItem pdfa = null; + + Iterator it = items.iterator(); + HttpSession session = request.getSession(); + while (it.hasNext()) + { + FileItem item = (FileItem) it.next(); + log.debug("item = " + item.getFieldName()); //$NON-NLS-1$ + + if (log.isDebugEnabled()) + { + if (item.isFormField()) + { + String item_string = item.getString("UTF-8"); //$NON-NLS-1$ + log.debug(" form field string = " + item_string); //$NON-NLS-1$ + } + else + { + log.debug(" filename = " + item.getName()); //$NON-NLS-1$ + log.debug(" filesize = " + item.getSize()); //$NON-NLS-1$ + } + } + + if (item.getFieldName().equals(FormFields.FIELD_PREVIEW)) + { + preview_fi = item; + continue; + } + + if (item.getFieldName().equals(FormFields.FIELD_SIGNATURE_TYPE)) + { + sig_type_fi = item; + session.setAttribute(UpdateFormServlet.UPLOADFORM_SIGNATURE_TYPE_KEY, sig_type_fi.getString("UTF-8")); + continue; + } + + if (item.getFieldName().equals(FormFields.FIELD_CONNECTOR)) + { + sig_app_fi = item; + session.setAttribute(UpdateFormServlet.UPLOADFORM_SIGNATURE_DEVICE_KEY, sig_app_fi.getString("UTF-8")); + continue; + } + + if (item.getFieldName().equals(FormFields.FIELD_MODE)) + { + mode_fi = item; + session.setAttribute(UpdateFormServlet.UPLOADFORM_SIGNATURE_MODE_KEY, mode_fi.getString("UTF-8")); + continue; + } + + if (item.getFieldName().equals(FormFields.FIELD_UPLOAD)) + { + file_upload_fi = item; + continue; + } + + if (item.getFieldName().equals(FormFields.FIELD_DOWNLOAD)) + { + download_fi = item; + continue; + } + + if (FormFields.FIELD_PDFA_ENABLED.equals(item.getFieldName())) { + pdfa = item; + session.setAttribute(UpdateFormServlet.UPLOADFORM_PDFA_KEY, pdfa.getString("UTF-8")); + continue; + } + + if (FormFields.FIELD_FREETEXT.equals(item.getFieldName())) { + freeText = item; + String value = freeText.getString("UTF-8"); + if (value != null) { + session.setAttribute(UpdateFormServlet.UPLOADFORM_FREETEXT_KEY, value); + } + continue; + } + + if (FormFields.FIELD_SOURCE.equals(item.getFieldName())) { + session.setAttribute(UpdateFormServlet.UPLOADFORM_SOURCE_KEY, item.getString("UTF-8")); + continue; + } + + throw new ServletException("Unrecognized POST data."); //$NON-NLS-1$ + + } + + if (preview_fi == null || sig_type_fi == null || sig_app_fi == null || (file_upload_fi == null && freeText== null) || download_fi == null) + { + throw new ServletException("Insufficient data provided in request"); //$NON-NLS-1$ + } + + String mode = mode_fi.getString("UTF-8"); //$NON-NLS-1$ + if (!mode.equals(FormFields.VALUE_MODE_BINARY) && !mode.equals(FormFields.VALUE_MODE_TEXTUAL) && !mode.equals(FormFields.VALUE_MODE_DETACHED)) + { + throw new ServletException("The mode '" + mode + "' is unrecognized."); //$NON-NLS-1$ //$NON-NLS-2$ + } + + String preview_str = preview_fi.getString("UTF-8"); //$NON-NLS-1$ + boolean preview = false; + if (preview_str.equals("true")) //$NON-NLS-1$ + { + preview = true; + } + + boolean download_inline = true; + if (download_fi.getString("UTF-8").equals(FormFields.VALUE_DOWNLOAD_ATTACHMENT)) //$NON-NLS-1$ + { + download_inline = false; + } + + String sig_type = sig_type_fi.getString("UTF-8"); //$NON-NLS-1$ + String sig_app = sig_app_fi.getString("UTF-8"); //$NON-NLS-1$ + + DataSource pdfDataSource; + String doc_file_name = "nofilename"; + // distinguish between file and freetext + if (file_upload_fi != null) { + log.debug("Processing file."); + File f = new File(file_upload_fi.getName()); + doc_file_name = f.getName(); + log.debug("file content type =" + file_upload_fi.getContentType()); //$NON-NLS-1$ + + String extension = VerifyServlet.extractExtension(doc_file_name); + if (extension != null && !extension.equals("pdf")) //$NON-NLS-1$ + { + throw new PDFDocumentException(201, "The provided file '" + doc_file_name + "' doesn't have the PDF extension (.pdf)."); //$NON-NLS-1$//$NON-NLS-2$ + } + + if (file_upload_fi.getSize() <= 0) + { + throw new PDFDocumentException(250, "The document is empty."); //$NON-NLS-1$ + } + + try + { + pdfDataSource = new ByteArrayPdfDataSource(IOUtils.toByteArray(file_upload_fi.getInputStream())); + } + catch (IOException e) + { + throw new PDFDocumentException(201, "Couldn't store the file in the temp dir.", e); + } + } else { + log.debug("Processing free text."); + try { + boolean pdfaEnabled = pdfa != null && "true".equalsIgnoreCase(pdfa.getString()); + byte[] freeTextPDF = IText.createPDF(freeText.getString("UTF-8"), pdfaEnabled); + + pdfDataSource = new ByteArrayPdfDataSource(freeTextPDF); + doc_file_name = IText.DEFAULT_FILENAME; + } catch (DocumentException e) { + throw new PDFDocumentException(201, "Unable to create PDF document.", e); + } catch (IOException e) { + throw new PDFDocumentException(201, "Unable to create PDF document.", e); + } + + } + // byte[] pdf = file_upload_fi.get(); + + UploadedData ud = new UploadedData(); + + ud.preview = preview; + ud.download_inline = download_inline; + ud.sig_type = sig_type; + ud.sig_app = sig_app; + ud.sig_mode = mode; + ud.file_name = doc_file_name; + ud.pdfDataSource = pdfDataSource; + + return ud; + } + + + + + + public static void prepareDispatchToErrorPage(PdfAsException pe, HttpServletRequest request) + { + request.setAttribute("PresentableException", pe); +// if (pe instanceof ErrorCodeException) +// { + request.setAttribute("error", "Fehler " + pe.getErrorCode()); + + String cause = ErrorCodeHelper.getMessageForErrorCode(pe.getErrorCode()); + + if (pe instanceof ExternalErrorException) + { + ExternalErrorException eee = (ExternalErrorException) pe; + cause = eee.getExternalErrorCode() + ": " + eee.getExternalErrorMessage(); + } + request.setAttribute("cause", cause); + + if (pe.getErrorCode() == ErrorCode.PLACEHOLDER_EXCEPTION) + { + PlaceholderException phe = null; + if (pe instanceof PlaceholderException) + { + phe = (PlaceholderException) pe; + } + else + { + phe = (PlaceholderException) pe.getCause(); + } + + request.setAttribute("cause", "Der Platzhalter des Feldes " + phe.getField() + " ist um " + phe.getMissing() + " Bytes zu kurz. " + cause); + } +// } +// else +// { +// request.setAttribute("error", "PresentableException"); +// request.setAttribute("cause", pe.toString()); +// } + } + + public void dispatchToPreview(String document_text, String connector, String mode, String signature_type, String submit_url, HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + request.setAttribute("document_text", document_text); + request.setAttribute("connector", connector); + request.setAttribute("mode", mode); + request.setAttribute("signature_type", signature_type); + request.setAttribute("submit_url", submit_url); + + dispatch(request, response, "/jsp/signpreview.jsp"); + } + + /** + * Formats the file name so that it is suitable for content disposition. + * + * @param file_name + * The file name. + * @return Returns the formatted file name. + */ + public static String formatFileName(String file_name) + { + File file = new File(file_name); + String file_name_only = file.getName(); + // the file_name contains \\ ==> remove them so Internet Explorer works + // correctly. + return file_name_only; + } + + + + + + // tzefferer: added + public static byte[] toByteArray(InputStream inputStream) throws IOException + { + + if (inputStream == null) + { + return null; + } + + ByteArrayOutputStream out = new ByteArrayOutputStream(8192); + int n; + byte[] buffer = new byte[2048]; + BufferedInputStream bufIn = new BufferedInputStream(inputStream); + try + { + while ((n = bufIn.read(buffer)) != -1) + { + out.write(buffer, 0, n); + } + } + finally + { + if (bufIn != null) + { + bufIn.close(); + } + } + return out.toByteArray(); + } + + // end add + + protected static class UploadedData + { + protected boolean preview = false; + + protected boolean download_inline = false; + + protected String sig_type = null; + + protected String sig_app = null; + + protected String sig_mode = null; + + protected String file_name = null; + + protected DataSource pdfDataSource = null; + // protected byte[] pdf = null; + } +} \ No newline at end of file -- cgit v1.2.3