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 --- .../gv/egiz/pdfas/web/CurrentLocalOperation.java | 84 +++ .../at/gv/egiz/pdfas/web/ExternAppInformation.java | 28 + .../main/java/at/gv/egiz/pdfas/web/FormFields.java | 196 ++++++ .../java/at/gv/egiz/pdfas/web/LocalRequest.java | 80 +++ .../java/at/gv/egiz/pdfas/web/PDFContainer.java | 27 + .../pdfas/web/PdfASServletContextListener.java | 134 ++++ .../gv/egiz/pdfas/web/filter/EncodingFilter.java | 123 ++++ .../at/gv/egiz/pdfas/web/helper/ApiHelper.java | 73 +++ .../egiz/pdfas/web/helper/LocalRequestHelper.java | 331 ++++++++++ .../at/gv/egiz/pdfas/web/helper/SessionHelper.java | 47 ++ .../egiz/pdfas/web/helper/SignServletHelper.java | 342 ++++++++++ .../egiz/pdfas/web/helper/SigningTimeHelper.java | 71 ++ .../egiz/pdfas/web/helper/WebSettingsReader.java | 210 ++++++ .../java/at/gv/egiz/pdfas/web/helper/WebUtils.java | 92 +++ .../pdfas/web/i18n/LanguageDecoratorMapper.java | 125 ++++ .../gv/egiz/pdfas/web/i18n/LocaleParamFilter.java | 96 +++ .../at/gv/egiz/pdfas/web/io/ByteArrayDataSink.java | 49 ++ .../egiz/pdfas/web/io/ByteArrayPdfDataSource.java | 41 ++ .../at/gv/egiz/pdfas/web/io/TextDataSource.java | 50 ++ .../java/at/gv/egiz/pdfas/web/itext/IText.java | 111 ++++ .../web/servlets/AsynchronousDataResponder.java | 157 +++++ .../servlets/AsynchronousRedirectResponder.java | 184 ++++++ .../gv/egiz/pdfas/web/servlets/DataURLServlet.java | 390 +++++++++++ .../egiz/pdfas/web/servlets/ProvidePDFServlet.java | 119 ++++ .../web/servlets/RetrieveSignatureDataServlet.java | 129 ++++ .../pdfas/web/servlets/SignPreviewServlet.java | 76 +++ .../at/gv/egiz/pdfas/web/servlets/SignServlet.java | 656 +++++++++++++++++++ .../egiz/pdfas/web/servlets/UpdateFormServlet.java | 56 ++ .../pdfas/web/servlets/VerifyPreviewServlet.java | 717 +++++++++++++++++++++ .../gv/egiz/pdfas/web/servlets/VerifyServlet.java | 479 ++++++++++++++ .../egiz/pdfas/web/session/SessionAttributes.java | 62 ++ .../pdfas/web/session/SignSessionInformation.java | 154 +++++ .../web/session/VerifySessionInformation.java | 198 ++++++ 33 files changed, 5687 insertions(+) create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/CurrentLocalOperation.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ExternAppInformation.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/FormFields.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/LocalRequest.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/PDFContainer.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/PdfASServletContextListener.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/EncodingFilter.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/ApiHelper.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/LocalRequestHelper.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SessionHelper.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SigningTimeHelper.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/WebSettingsReader.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/WebUtils.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/i18n/LanguageDecoratorMapper.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/i18n/LocaleParamFilter.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/io/ByteArrayDataSink.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/io/ByteArrayPdfDataSource.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/io/TextDataSource.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/itext/IText.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/AsynchronousDataResponder.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/AsynchronousRedirectResponder.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ProvidePDFServlet.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/RetrieveSignatureDataServlet.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignPreviewServlet.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignServlet.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UpdateFormServlet.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyPreviewServlet.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyServlet.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/session/SessionAttributes.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/session/SignSessionInformation.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/session/VerifySessionInformation.java (limited to 'pdf-as-web/src/main/java/at/gv') diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/CurrentLocalOperation.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/CurrentLocalOperation.java new file mode 100644 index 0000000..96194bf --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/CurrentLocalOperation.java @@ -0,0 +1,84 @@ +/** + * + */ +package at.gv.egiz.pdfas.web; + +import java.util.List; + + +/** + * Encapsulates a local operation. + * + *

+ * A local operation is a sequence of successive local verifications. + *

+ *

+ * This is held on the VerifySessionInformation so that the DataURLServlet and RetrieveSignatureDataServlet + * can provide their data to the local service easily. + *

+ * + * @author wprinz + */ +public class CurrentLocalOperation +{ + + /** + * The signature holders to be verified in the current local operation. + */ + public List signaturesToBeverified; + + + /** + * An array of local requests to be processed. + */ + public LocalRequest[] requests = null; + + /** + * An array of response strings of the local requests. + */ + public String[] response_xmls = null; + + /** + * The index of the holder/request to be processed. + */ + public int current_operation = 0; + +// /** +// * Tells, if the current local request has been finished. +// */ +// public boolean finished = false; + + /** + * @see at.gv.egiz.pdfas.web.LocalOperation#isFinished() + */ + public boolean isFinished() + { + return this.current_operation >= this.requests.length; + } + + /** + * @see at.gv.egiz.pdfas.web.LocalOperation#getCurrentLocalRequest() + */ + public LocalRequest getCurrentLocalRequest() + { + return this.requests[this.current_operation]; + } + +// /** +// * @see at.gv.egiz.pdfas.web.LocalOperation#getCurrentSignatureHolder() +// */ +// public SignatureHolder getCurrentSignatureHolder() +// { +// return (SignatureHolder) this.holders_to_be_verified.get(this.current_operation); +// } + + /** + * @see at.gv.egiz.pdfas.web.LocalOperation#finishCurrentOperation(java.util.Properties) + */ + public void finishCurrentOperation(String xml_response) + { + this.response_xmls[this.current_operation] = xml_response; + + this.current_operation++; + } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ExternAppInformation.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ExternAppInformation.java new file mode 100644 index 0000000..8e44ace --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ExternAppInformation.java @@ -0,0 +1,28 @@ +package at.gv.egiz.pdfas.web; + +import java.io.Serializable; + +public class ExternAppInformation implements Serializable { + + /** + * SVUID. + */ + private static final long serialVersionUID = 1L; + + public String invoke_url; + public long pdf_id; + public String session_id; + public String invoke_error_url; + + public ExternAppInformation(String url, String id, String session_id) { + this(url, id, session_id, null); + } + + public ExternAppInformation(String url, String id, String session_id, String errorUrl) { + this.invoke_url = url; + this.pdf_id = Long.parseLong(id); + this.session_id = session_id; + this.invoke_error_url = errorUrl; + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/FormFields.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/FormFields.java new file mode 100644 index 0000000..bc768b4 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/FormFields.java @@ -0,0 +1,196 @@ +/** + * 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: FormFields.java,v 1.4 2006/10/11 07:39:13 wprinz Exp $ + */ +package at.gv.egiz.pdfas.web; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; + +import at.gv.egiz.pdfas.api.PdfAs; +import at.gv.egiz.pdfas.api.commons.SignatureProfile; +import at.gv.egiz.pdfas.api.internal.PdfAsInternal; +import at.gv.egiz.pdfas.web.helper.ApiHelper; +import at.knowcenter.wag.egov.egiz.exceptions.ConnectorFactoryException; +import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; + +/** + * Helper class that provides methods and constants for creating and dealing + * with the various form fields. + * + * @author wprinz + */ +public abstract class FormFields +{ + public static final String FIELD_UPLOAD = "upload"; + + public static final String FIELD_CONNECTOR = "connector"; + + public static final String FIELD_MODE = "mode"; + + public static final String FIELD_PREVIEW = "preview"; + + public static final String FIELD_RAW_DOCUMENT_TEXT = "raw_document_text"; + + public static final String FIELD_SIGNATURE_TYPE = "sig_type"; + + // tknall: PDF/A-1b enabled + public static final String FIELD_PDFA_ENABLED = "pdfa_enabled"; + + public static final String FIELD_VERIFY_WHICH = "verify_which"; + + public static final String FIELD_SIGNED_TEXT = "signed_text"; + + public static final String FIELD_DOWNLOAD = "download"; + + public static final String VALUE_TRUE = "true"; + + public static final String VALUE_FALSE = "false"; + + public static final String VALUE_MODE_BINARY = "binary"; + + public static final String VALUE_MODE_TEXTUAL = "textual"; + + public static final String VALUE_MODE_DETACHED = "detached"; + + public static final String VALUE_VERIFY_WHICH_ALL = "all"; + + public static final String VALUE_DOWNLOAD_INLINE = "inline"; + + public static final String VALUE_DOWNLOAD_ATTACHMENT = "attachment"; + + protected static final String STYLE_CLASS_FIELD = "field"; + + // tzefferer: added fields for URL requests + + public static final String FIELD_FILENAME = "filename"; + + public static final String FIELD_PDF_URL = "pdf-url"; + + public static final String FIELD_PDF_ID = "pdf-id"; + + public static final String FIELD_PDFAS_SESSION_ID = "pdfas-session-id"; + + public static final String FIELD_FILE_LENGTH = "num-bytes"; + + public static final String FIELD_INVOKE_APP_URL = "invoke-app-url"; + + public static final String FIELD_INVOKE_APP_ERROR_URL = "invoke-app-error-url"; + + public static final String FIELD_SESSION_ID = "session-id"; + + public static final String FIELD_SIGPOS_Y = "sig-pos-y"; + + public static final String FIELD_SIGPOS_P = "sig-pos-p"; + + public static final String FIELD_SOURCE = "source_filefreetext"; + + public static final String VALUE_SOURCE_FILE = "source-is-file"; + + public static final String VALUE_SOURCE_FREETEXT = "source-is-freetext"; + + public static final String FIELD_FREETEXT = "freetext"; + + // end add + /** + * The settings key prefix for signature definitions. "sig_obj." + */ + public static final String SIG_OBJ = "sig_obj."; + + /** + * The settings key postfix for the type description + */ + public static final String SIG_DESCR = "description"; + + + /** + * Generates the HTML snippet of a FIELD_CONNECTOR select box that allows to + * choose a connector. + * + * @return Returns the HTML snippet. + * @throws SettingsException + * Forwarded exception. + * @throws ConnectorFactoryException + * Forwarded exception. + */ + public static String generateConnectorSelectBox(ServletContext sc) throws ConnectorFactoryException + { + StringWriter sw = new StringWriter(); + PrintWriter writer = new PrintWriter(sw); + + writer.println(""); + + return sw.toString(); + } + + /** + * Generates a HTML snippet of a FIELD_SIGNATURE_TYPE select box that allows + * to choose the signature type. + * + * @return Returns the HTML snippet. + * @throws ServletException + * Forwarded exception. + */ + public static String generateTypeSelectBox(ServletContext sc) throws ServletException + { + try + { + StringWriter sw = new StringWriter(); + PrintWriter writer = new PrintWriter(sw); + + PdfAs pdfAs = ApiHelper.getPdfAsFromContext(sc); + List profiles = pdfAs.getProfileInformation(); + + writer.println(""); + + return sw.toString(); + } + catch (Exception e) + { + throw new ServletException(e); + } + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/LocalRequest.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/LocalRequest.java new file mode 100644 index 0000000..2037edd --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/LocalRequest.java @@ -0,0 +1,80 @@ +/** + * 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: LocalRequest.java,v 1.2 2006/08/25 17:06:11 wprinz Exp $ + */ +package at.gv.egiz.pdfas.web; + +import java.io.Serializable; + +/** + * Encapsulates a local request, basicall an URL where the local request is sent + * to and a request string. + * + * @author wprinz + */ +public class LocalRequest implements Serializable +{ + + /** + * SVUID. + */ + private static final long serialVersionUID = -3734904043231861998L; + + /** + * The URL the local request sould be directed at. + */ + protected String url_; + + /** + * The request string to be sent to that URL. + */ + protected String request_string_; + + /** + * Constructor that initializes the URL and request string. + * + * @param url + * The URL the local request sould be directed at. + * @param request_string + * The request string to be sent to that URL. + */ + public LocalRequest(String url, String request_string) + { + this.url_ = url; + this.request_string_ = request_string; + } + + /** + * Returns the URL. + * + * @return Returns the URL. + */ + public String getUrl() + { + return url_; + } + + /** + * Returns the request string. + * + * @return Returns the request string. + */ + public String getRequestString() + { + return request_string_; + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/PDFContainer.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/PDFContainer.java new file mode 100644 index 0000000..bf49224 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/PDFContainer.java @@ -0,0 +1,27 @@ +package at.gv.egiz.pdfas.web; + +public class PDFContainer { + + public long id; + public byte[] pdf; + + + public PDFContainer(byte[] pdf, long id) { + this.id = id; + this.pdf = pdf; + } + + public boolean equals(Object pc) { + if(pc instanceof PDFContainer) { + return (this.id == ((PDFContainer)pc).id); + } + return false; + } + public int hashCode() { + Long l = new Long(this.id); + return l.intValue(); + } + +} + + diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/PdfASServletContextListener.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/PdfASServletContextListener.java new file mode 100644 index 0000000..ac0c4c5 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/PdfASServletContextListener.java @@ -0,0 +1,134 @@ +/** + * 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: PdfASServletContextListener.java,v 1.3 2006/10/31 08:22:04 wprinz Exp $ + */ +package at.gv.egiz.pdfas.web; + +import java.io.File; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import at.gv.egiz.pdfas.api.PdfAs; +import at.gv.egiz.pdfas.api.commons.Constants; +import at.gv.egiz.pdfas.api.internal.PdfAsInternal; +import at.gv.egiz.pdfas.web.helper.ApiHelper; +import at.gv.egiz.pdfas.web.helper.WebSettingsReader; +import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; +import at.knowcenter.wag.egov.egiz.exceptions.WebException; + +/** + * The ServletContextListener is notified when the webapplication starts up and + * shuts down. + * + *

+ * Maintainance work is performed. + *

+ * + * @author wprinz + */ +public class PdfASServletContextListener implements ServletContextListener { + /** + * The logger. + */ + private static final Logger logger = Logger.getLogger(PdfASServletContextListener.class); + + /** + * The servlet init parameter that may be used to declare the pdf-as + * configuration folder. The init parameter may be set in web.xml or in + * META-INF/context.xml resp. conf/Catalina/localhost/pdf-as.xml if deployed. + */ + private final static String CONFIG_SERVLET_INIT_PARAMETER = "work-dir"; + + /** + * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent) + */ + public void contextInitialized(ServletContextEvent sce) { + logger.info("PDF-AS Context init"); //$NON-NLS-1$ + + String sysPropWorkdir = System.getProperty(Constants.CONFIG_DIR_SYSTEM_PROPERTY); + String scWorkdir = sce.getServletContext().getInitParameter(CONFIG_SERVLET_INIT_PARAMETER); + + String work_dir; + + // search for system property + if (!StringUtils.isEmpty(sysPropWorkdir)) { + work_dir = sysPropWorkdir; + logger.debug("Work-dir configuration via system property \"" + + Constants.CONFIG_DIR_SYSTEM_PROPERTY + "\" = \"" + sysPropWorkdir + "\"."); + + // search for servlet parameter + } else if (!StringUtils.isEmpty(scWorkdir)) { + work_dir = scWorkdir; + logger.debug("Work-dir configuration via servlet init parameter \"" + + CONFIG_SERVLET_INIT_PARAMETER + "\" = \"" + scWorkdir + "\"."); + + // assume configuration to be located in webapp path + } else { + work_dir = sce.getServletContext().getRealPath("/"); + logger.info("PDF-AS work-dir not explicitely given. Assuming configuration is located in webapp folder \"" + + work_dir + "\"."); + } + + logger.info("PDF-AS configuration location = \"" + work_dir + "\""); + + // try + // { + // logger.info("PDF-AS work directory = " + new File(work_dir).getCanonicalPath()); //$NON-NLS-1$ + // logger.info("PDF-AS base directory = " + new File(base_dir).getCanonicalPath()); //$NON-NLS-1$ + // } + // catch (IOException e) + // { + // e.printStackTrace(); + // } + + WebSettingsReader.initialize(work_dir); + PdfAs pdfAs; + try { + pdfAs = ApiHelper.createApiObject(new File(WebSettingsReader.RESOURCES_PATH)); + sce.getServletContext().setAttribute(ApiHelper.PDF_AS_OBJECT, pdfAs); + } catch (WebException e) { + logger.error(e.getMessage(), e); + } + + PdfAsInternal pdfAsInternal; + try { + pdfAsInternal = ApiHelper.createInternalApiObject(); + sce.getServletContext().setAttribute(ApiHelper.INTERNAL_PDF_AS_OBJECT, pdfAsInternal); + } catch (WebException e) { + logger.error(e.getMessage(), e); + } + + try { + WebSettingsReader.getInstance(); + } catch (SettingsException e) { + logger.error(e.getMessage(), e); + } + + WebSettingsReader.clearTemporaryDirectory(); + } + + /** + * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) + */ + public void contextDestroyed(ServletContextEvent sce) { + WebSettingsReader.clearTemporaryDirectory(); + logger.info("PDF-AS Context exit"); //$NON-NLS-1$ + } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/EncodingFilter.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/EncodingFilter.java new file mode 100644 index 0000000..5267918 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/EncodingFilter.java @@ -0,0 +1,123 @@ +package at.gv.egiz.pdfas.web.filter; + +import java.io.IOException; +import java.nio.charset.Charset; + +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.log4j.Logger; + +/** + * @author Thomas Knall + */ +public class EncodingFilter implements javax.servlet.Filter { + + private static final String SERVLET_INIT_PARAM_ENCODING = "encoding"; + + private static final String SERVLET_INIT_PARAM_SET_REQUEST_ENCODING = "setRequestEncoding"; + private static final String SERVLET_INIT_PARAM_FORCE_REQUEST_ENCODING = "forceRequestEncoding"; + + private static final String SERVLET_INIT_PARAM_SET_RESPONSE_ENCODING = "setResponseEncoding"; + private static final String SERVLET_INIT_PARAM_FORCE_RESPONSE_ENCODING = "forceResponseEncoding"; + + private static final boolean DEFAULT_SET_REQUEST_ENCODING_VALUE = true; + private static final boolean DEFAULT_FORCE_REQUEST_ENCODING_VALUE = true; + private static final boolean DEFAULT_SET_RESPONSE_ENCODING_VALUE = false; + private static final boolean DEFAULT_FORCE_RESPONSE_ENCODING_VALUE = false; + + private Logger log = Logger.getLogger(getClass().getName()); + + private String encoding = null; + + private boolean setRequestEncoding; + private boolean forceRequestEncoding; + + private boolean setResponseEncoding; + private boolean forceResponseEncoding; + + private boolean enabled = false; + + private boolean parseBooleanInitParameter(final FilterConfig filterConfig, String parameterName, boolean defaultValue) { + String paramValue = filterConfig.getInitParameter(parameterName); + if (paramValue == null) { + return defaultValue; + } + paramValue = paramValue.trim(); + if (paramValue.equalsIgnoreCase("true")) { + return true; + } else if (paramValue.equalsIgnoreCase("false")){ + return false; + } else { + log.warn("Unknown value \"" + paramValue + "\" for init parameter \"" + parameterName + "\" detected. Should be \"true\" or \"false\". Using default value \"" + defaultValue + "\"."); + return defaultValue; + } + } + + public void init(final FilterConfig filterConfig) throws ServletException { + log.debug("Initializing encoding filter (" + getClass().getName() + ")."); + + // mandatory parameter encoding + String desiredEncoding = filterConfig.getInitParameter(SERVLET_INIT_PARAM_ENCODING); + if (StringUtils.isEmpty(desiredEncoding)) { + log.warn("Unable to initialize encoding filter (" + getClass().getName() + "). Init parameter \"" + SERVLET_INIT_PARAM_ENCODING + "\" empty or not supplied."); + } else if (!Charset.isSupported(desiredEncoding)) { + log.warn("Unable to initialize encoding filter (" + getClass().getName() + "). Encoding \"" + desiredEncoding + "\" is not supported."); + } else { + this.encoding = desiredEncoding; + this.enabled = true; + this.setRequestEncoding = this.parseBooleanInitParameter(filterConfig, SERVLET_INIT_PARAM_SET_REQUEST_ENCODING, DEFAULT_SET_REQUEST_ENCODING_VALUE); + this.forceRequestEncoding = this.parseBooleanInitParameter(filterConfig, SERVLET_INIT_PARAM_FORCE_REQUEST_ENCODING, DEFAULT_FORCE_REQUEST_ENCODING_VALUE); + this.setResponseEncoding = this.parseBooleanInitParameter(filterConfig, SERVLET_INIT_PARAM_SET_RESPONSE_ENCODING, DEFAULT_SET_RESPONSE_ENCODING_VALUE); + this.forceResponseEncoding = this.parseBooleanInitParameter(filterConfig, SERVLET_INIT_PARAM_FORCE_RESPONSE_ENCODING, DEFAULT_FORCE_RESPONSE_ENCODING_VALUE); + log.debug("Encoding filter \"" + getClass().getName() + "\" configured: " + this.toString(true)); + + } + } + + public String toString(boolean verbose) { + if (verbose) { + return new ToStringBuilder(this) + .append(SERVLET_INIT_PARAM_ENCODING, this.encoding) + .append(SERVLET_INIT_PARAM_SET_REQUEST_ENCODING, this.setRequestEncoding) + .append(SERVLET_INIT_PARAM_FORCE_REQUEST_ENCODING, this.forceRequestEncoding) + .append(SERVLET_INIT_PARAM_SET_RESPONSE_ENCODING, this.setResponseEncoding) + .append(SERVLET_INIT_PARAM_FORCE_RESPONSE_ENCODING, this.forceResponseEncoding) + .toString(); + } else { + return super.toString(); + } + } + + public void doFilter(ServletRequest request, ServletResponse response, final FilterChain filterChain) throws IOException, ServletException { + if (this.enabled) { + if (this.setRequestEncoding) { + if (this.forceRequestEncoding) { + log.trace("Forcing request encoding \"" + this.encoding + "\"."); + request.setCharacterEncoding(this.encoding); + } else if (request.getCharacterEncoding() == null) { + log.trace("Request character encoding not set. Setting to \"" + this.encoding + "\"."); + request.setCharacterEncoding("UTF8"); + } + } + if (this.setResponseEncoding) { + if (this.forceResponseEncoding) { + log.trace("Forcing response encoding \"" + this.encoding + "\"."); + response.setCharacterEncoding(this.encoding); + } else if (response.getCharacterEncoding() == null) { + log.trace("Response character encoding not set. Setting to \"" + this.encoding + "\"."); + response.setCharacterEncoding("UTF8"); + } + } + } + filterChain.doFilter(request, response); + } + + public void destroy() { + } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/ApiHelper.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/ApiHelper.java new file mode 100644 index 0000000..a0f22fd --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/ApiHelper.java @@ -0,0 +1,73 @@ +package at.gv.egiz.pdfas.web.helper; + +import java.io.File; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +import javax.servlet.ServletContext; + +import at.gv.egiz.pdfas.api.PdfAs; +import at.gv.egiz.pdfas.api.internal.PdfAsInternal; +import at.knowcenter.wag.egov.egiz.exceptions.WebException; + +/** + * Utility methods for easier handling of {@link PdfAs} API object. + * + * @author exthex + * + */ +public class ApiHelper { + + public static final String PDF_AS_OBJECT = "PDF_AS_OBJECT"; + + public static final String INTERNAL_PDF_AS_OBJECT = "INTERNAL_PDF_AS_OBJECT"; + + public static PdfAs createApiObject(File file) throws WebException { + try { + Class pdfAsClass = Class.forName("at.gv.egiz.pdfas.impl.api.PdfAsObject"); + Constructor constructor = pdfAsClass.getConstructor(new Class[]{File.class}); + PdfAs pdfAs = (PdfAs)constructor.newInstance(new Object[]{ + new File(WebSettingsReader.RESOURCES_PATH)}); + return pdfAs; + } catch (ClassNotFoundException e) { + throw new WebException(e); + } catch (SecurityException e) { + throw new WebException(e); + } catch (NoSuchMethodException e) { + throw new WebException(e); + } catch (IllegalArgumentException e) { + throw new WebException(e); + } catch (InstantiationException e) { + throw new WebException(e); + } catch (IllegalAccessException e) { + throw new WebException(e); + } catch (InvocationTargetException e) { + throw new WebException(e); + } + } + + public static PdfAsInternal createInternalApiObject() throws WebException { + try { + Class pdfAsClass = Class.forName("at.gv.egiz.pdfas.impl.api.internal.PdfAsInternalObject"); + PdfAsInternal pdfAsinternal = (PdfAsInternal)pdfAsClass.newInstance(); + return pdfAsinternal; + } catch (ClassNotFoundException e) { + throw new WebException(e); + } catch (SecurityException e) { + throw new WebException(e); + } catch (InstantiationException e) { + throw new WebException(e); + } catch (IllegalAccessException e) { + throw new WebException(e); + } + } + + public static PdfAs getPdfAsFromContext(ServletContext servletContext) { + return (PdfAs)servletContext.getAttribute(PDF_AS_OBJECT); + } + + public static PdfAsInternal getPdfAsInternalFromContext(ServletContext servletContext) { + return (PdfAsInternal)servletContext.getAttribute(INTERNAL_PDF_AS_OBJECT); + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/LocalRequestHelper.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/LocalRequestHelper.java new file mode 100644 index 0000000..82b3983 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/LocalRequestHelper.java @@ -0,0 +1,331 @@ +/** + * 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: LocalRequestHelper.java,v 1.6 2006/10/31 08:22:04 wprinz Exp $ + */ +package at.gv.egiz.pdfas.web.helper; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.List; +import java.util.Properties; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.api.commons.Constants; +import at.gv.egiz.pdfas.api.commons.SignatureInformation; +import at.gv.egiz.pdfas.api.internal.PdfAsInternal; +import at.gv.egiz.pdfas.web.CurrentLocalOperation; +import at.gv.egiz.pdfas.web.LocalRequest; +import at.gv.egiz.pdfas.web.session.SignSessionInformation; +import at.gv.egiz.pdfas.web.session.VerifySessionInformation; +import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; +import at.knowcenter.wag.egov.egiz.exceptions.ConnectorFactoryException; +import at.knowcenter.wag.egov.egiz.exceptions.NormalizeException; +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; +import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; +import at.knowcenter.wag.egov.egiz.exceptions.SignatureException; + +/** + * Contains commonly used helper functions for the local request procedure. + * + * @author wprinz + */ +public abstract class LocalRequestHelper +{ + + /** + * The logger. + */ + protected static Log logger = LogFactory.getLog(LocalRequestHelper.class); + + /** + * The resource of the null request page jsp. + */ + public static final String NULL_REQUEST_PAGE_JSP = "/jsp/null_request_page.jsp"; + + /** + * The resource of the local connection page jsp. + */ + public static final String LOCAL_CONNECTION_PAGE_JSP = "/jsp/local_connection_page.jsp"; + + /** + * The resource of the redirect refresh page jsp. + */ + public static final String REDIRECT_REFRESH_PAGE_JSP = "/jsp/redirect_refresh_page.jsp"; + + /** + * Sets up the local sign procedure. + * + * @param response + * The HttpServletResponse the local request page is written to. + * @throws IOException + * Forwarded exception. + * @throws PresentableException + * Forwarded exception. + */ + public static String processLocalSign(PdfAsInternal pdfAsInternal, SignSessionInformation si, HttpServletRequest request, HttpServletResponse response) throws IOException, PresentableException + { + String host = request.getServerName(); +// URL loc_ref_URL = new URL(WebUtils.addJSessionID(getLocalContextAddress(request, response) + "/RetrieveSignatureData", request)); + URL loc_ref_URL = new URL(WebUtils.buildRetrieveSignatureDataURL(request, response)); + String loc_ref_url = response.encodeURL(loc_ref_URL.toString()); + + String sign_request = pdfAsInternal.prepareLocalSignRequest(si.signParameters, loc_ref_url, si.sdi); +// LocalConnector c = ConnectorChooser.chooseLocalConnectorForSign(si.connector, si.type, loc_ref_url); +// String sign_request = c.prepareSignRequest(si.si.getSignatureData()); + + String local_request_url = pdfAsInternal.getLocalServiceAddress(si.type, si.connector); +// String local_request_url = getLocalServiceAddress(si.type, si.connector); + si.localRequest = new LocalRequest(local_request_url, sign_request); + si.outputAvailable = false; +// si.response_properties = null; + + URL data_URL = new URL(request.getScheme(), host, request.getServerPort(), WebUtils.addJSessionID(request.getContextPath() + "/DataURL", request)); + String data_url = response.encodeURL(data_URL.toString()); + logger.debug("data_url = " + data_url); + + request.setAttribute("local_request_url", local_request_url); + request.setAttribute("data_url", data_url); + + return NULL_REQUEST_PAGE_JSP; + + // TODO old code - remove + // + // LocalConnector local_conn = (LocalConnector) + // ConnectorFactory.createConnector(si.connector); + // + // + // // refactor WEB + // String document_text = "fixme"; //si.iui.document_text; + // String request_string = local_conn.prepareSignRequest(si.user_name, + // document_text, si.type); + // String request_url = local_conn.getSignURL(si.type); + // + // LocalRequest local_request = new LocalRequest(request_url, + // request_string); + // List local_requests = new ArrayList(); + // local_requests.add(local_request); + // + // // ByteArrayOutputStream baos = new ByteArrayOutputStream(); + // // ObjectOutputStream oos = new ObjectOutputStream(baos); + // // oos.writeObject(local_requests); + // // oos.close(); + // // baos.close(); + // + // si.requests = new LocalRequest[1]; + // si.requests[0] = new LocalRequest(local_conn.getSignURL(si.type), + // request_string); + // si.current_operation = 0; + // si.response_properties = new Properties[1]; + // si.response_properties[0] = null; + // + // // SessionTable.put(si); + // request.getSession().setAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION, + // si); + // + // // byte [] requests_bytes = baos.toByteArray(); + // // String base64 = CodingHelper.encodeBase64(requests_bytes); + // + // LocalRequestHelper.prepareDispatchToLocalConnectionPage(si.requests[0], + // request, response); + } + + /** + * Sets up the local verify procedure. + * @param list + * + * @param response + * The HttpServletResponse the local request page is written to. + * @return Returns the JSP location where the calling servlet should dispatch + * to. + * @throws SignatureException + * Forwarded exception. + * @throws NormalizeException + * Forwarded exception. + * @throws IOException + * Forwarded exception. + * @throws ConnectorFactoryException + * Forwarded exception. + * @throws SettingsException + * @throws ConnectorException + */ + public static String processLocalVerify(PdfAsInternal pdfAsInternal, VerifySessionInformation si, List signaturesToBeverified, HttpServletRequest request, HttpServletResponse response) throws SignatureException, NormalizeException, + IOException, ConnectorFactoryException, SettingsException, ConnectorException + { + si.currentLocalOperation = new CurrentLocalOperation(); + si.currentLocalOperation.signaturesToBeverified = signaturesToBeverified; // SignatureInformation + + si.currentLocalOperation.requests = new LocalRequest[signaturesToBeverified.size()]; + si.currentLocalOperation.response_xmls = new String[si.currentLocalOperation.requests.length]; + + si.currentLocalOperation.current_operation = 0; +// si.finished = false; + + String host = request.getServerName(); +// URL loc_ref_URL = new URL(WebUtils.addJSessionID(getLocalContextAddress(request, response) + "/RetrieveSignatureData", request)); + URL loc_ref_URL = new URL(WebUtils.buildRetrieveSignatureDataURL(request, response)); + String loc_ref_url = response.encodeURL(loc_ref_URL.toString()); + + for (int i = 0; i < si.currentLocalOperation.requests.length; i++) + { + SignatureInformation sigInfo = (SignatureInformation) signaturesToBeverified.get(i); + String request_string = pdfAsInternal.prepareLocalVerifyRequest(sigInfo, si.connector, si.type, loc_ref_url); + + LocalRequest local_request = new LocalRequest("not-needed", request_string); + si.currentLocalOperation.requests[i] = local_request; + si.currentLocalOperation.response_xmls[i] = null; + } + + String local_request_url = pdfAsInternal.getLocalServiceAddress(si.type, si.connector); + + URL data_URL = new URL(request.getScheme(), host, request.getServerPort(), WebUtils.addJSessionID(request.getContextPath() + "/DataURL", request)); + String data_url = response.encodeURL(data_URL.toString()); + + request.setAttribute("local_request_url", local_request_url); + request.setAttribute("data_url", data_url); + + return NULL_REQUEST_PAGE_JSP; + + } + + /** + * Formats the OK response from the web application back to the local BKU. + * + *

+ * As stated in the BKU tutorial, this response must be plain text "". + * Otherwise BKU will assume a failure. + *

+ * + * @param response + * The HttpServletResponse to answer to. + * @throws IOException + * Forwarded exception. + */ + protected static void formatBKUOkResponse(HttpServletResponse response) throws IOException + { + response.setContentType("text/plain"); + response.setCharacterEncoding("ISO-8859-1"); + + response.getWriter().println(""); + } + + /** + * Prepares the dispatch to the local data connection page. + * + *

+ * The calling servlet just has to dispatch to the jsp after calling this + * method. + *

+ * + * @param local_request + * The local request. Basically this contains the local service's + * target URL and the XML request string. + * @param response + * The HttpServletResponse to write this page to. + * @throws IOException + * Forwarded exception. + * @throws SignatureException + * Forwarded exception. + * @throws NormalizeException + * Forwarded exception. + */ + public static void prepareDispatchToLocalConnectionPage(LocalRequest local_request, HttpServletRequest request, HttpServletResponse response) throws IOException, SignatureException, + NormalizeException + { + response.setContentType("text/html"); + response.setCharacterEncoding("UTF-8"); + + String local_request_url = local_request.getUrl(); + + String quoted_request = makeStringHTMLReady(local_request.getRequestString()); + + String host = request.getServerName(); // "129.27.153.77" + URL data_URL = new URL(request.getScheme(), host, request.getServerPort(), request.getContextPath() + "/AsynchronousDataResponder"); + String data_url = response.encodeURL(data_URL.toString()); + URL redirect_URL = new URL(request.getScheme(), host, request.getServerPort(), request.getContextPath() + "/AsynchronousRedirectResponder"); + String redirect_url = response.encodeURL(redirect_URL.toString()); + + request.setAttribute("local_request_url", local_request_url); + request.setAttribute("quoted_request", quoted_request); + request.setAttribute("data_url", data_url); + request.setAttribute("redirect_url", redirect_url); + } + + public static String makeStringHTMLReady(String input) + { + String output = input; + + output = output.replaceAll("&", "&"); + output = output.replaceAll("\"", """); + output = output.replaceAll("<", "<"); + output = output.replaceAll(">", ">"); + return output; + } + + public static String getLocalServerAddress(HttpServletRequest request, HttpServletResponse response) + { + String host = request.getServerName(); + URL local_server = null; + try + { + String scheme = request.getScheme(); + int port = request.getServerPort(); + if ("http".equalsIgnoreCase(scheme) && port == 80) { + local_server = new URL(scheme, host, "/"); + } else if ("https".equalsIgnoreCase(scheme) && port == 443) { + local_server = new URL(scheme, host, "/"); + } else { + local_server = new URL(scheme, host, port, "/"); + } + } + catch (MalformedURLException e) + { + logger.error(e.getMessage(), e); + } + String loc_server = response.encodeURL(local_server.toString()); + + return loc_server; + } + + public static String getLocalContextAddress(HttpServletRequest request, HttpServletResponse response) { + String serverURL = getLocalServerAddress(request, response); + String context = request.getContextPath(); + if (serverURL.endsWith("/") && context.startsWith("/")) { + context = context.substring(1); + } + return serverURL + context; + } + +/** + * Tells, if the given connector is local. + * + * @param connector_identifier + * The connector. + * @return Returns true, if the given connector is local, false otherwise. + * @throws ConnectorFactoryException + * F.e. + */ + public static boolean isConnectorLocal(String connector_identifier) throws ConnectorFactoryException + { + return connector_identifier.equals(Constants.SIGNATURE_DEVICE_BKU) || connector_identifier.equals(Constants.SIGNATURE_DEVICE_A1) || connector_identifier.equals(Constants.SIGNATURE_DEVICE_MOC); + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SessionHelper.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SessionHelper.java new file mode 100644 index 0000000..e3c8269 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SessionHelper.java @@ -0,0 +1,47 @@ +/** + * + */ +package at.gv.egiz.pdfas.web.helper; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.exceptions.web.SessionExpiredException; +import at.gv.egiz.pdfas.web.session.SessionAttributes; + +/** + * @author wprinz + * + */ +public class SessionHelper +{ + /** + * The log. + */ + private static Log log = LogFactory.getLog(SessionHelper.class); + + public static Object getSession(HttpServletRequest request) throws SessionExpiredException + { + + HttpSession session = request.getSession(false); + if (session == null) + { + String msg = "There is no session associated with this request."; //$NON-NLS-1$ + log.error(msg); + throw new SessionExpiredException(msg); + } + + Object sessionObject = session.getAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION); + if (sessionObject == null) + { + String msg = "Unable to find session data in session " + session.getId(); + log.error(msg); + throw new SessionExpiredException(msg); + } + + return sessionObject; + } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java new file mode 100644 index 0000000..779b37b --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java @@ -0,0 +1,342 @@ +/** + * + */ +package at.gv.egiz.pdfas.web.helper; + +import java.io.IOException; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.api.PdfAs; +import at.gv.egiz.pdfas.api.commons.Constants; +import at.gv.egiz.pdfas.api.exceptions.PdfAsException; +import at.gv.egiz.pdfas.api.internal.PdfAsInternal; +import at.gv.egiz.pdfas.api.io.DataSink; +import at.gv.egiz.pdfas.api.sign.SignParameters; +import at.gv.egiz.pdfas.api.sign.SignResult; +import at.gv.egiz.pdfas.api.sign.SignatureDetailInformation; +import at.gv.egiz.pdfas.web.FormFields; +import at.gv.egiz.pdfas.web.PDFContainer; +import at.gv.egiz.pdfas.web.io.ByteArrayDataSink; +import at.gv.egiz.pdfas.web.servlets.ProvidePDFServlet; +import at.gv.egiz.pdfas.web.session.SessionAttributes; +import at.gv.egiz.pdfas.web.session.SignSessionInformation; +import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; + +/** + * @author wprinz + * + */ +public class SignServletHelper +{ + /** + * The log. + */ + private static Log log = LogFactory.getLog(SignServletHelper.class); + + public 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); + } + + + /** + * Prepares the sign. + * + *

+ * This prepares the data for both being signed or being previewed. + *

+ * + * @param si + * The SessionInformation to be prepared. + * @throws PdfAsException + */ + public static SignatureDetailInformation prepareSign(PdfAs pdfAs, SignSessionInformation si) throws PdfAsException + { + log.debug("prepareSign:"); //$NON-NLS-1$ + + SignParameters signParameters = new SignParameters(); + signParameters.setDocument(si.pdfDataSource); + signParameters.setSignatureDevice(si.connector); + signParameters.setSignaturePositioning(si.pos); + signParameters.setSignatureProfileId(si.type); + signParameters.setSignatureType(si.mode); + DataSink sink = new ByteArrayDataSink(); + signParameters.setOutput(sink); + + SignatureDetailInformation signatureDetail = pdfAs.prepareSign(signParameters); + si.sdi = signatureDetail; + si.signParameters = signParameters; +// PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode); +// Signator signator = SignatorFactory.createSignator(algorithm); + + // tzefferer: modified + // si.iui = signator.prepareSign(si.pdf, si.type, null, + // ConnectorFactory.needsSIG_ID(si.connector)); +// si.si = signator.prepareSign(si.pdfDataSource, si.type, si.pos, null); + // end modify + log.debug("prepareSign finished."); //$NON-NLS-1$ + return signatureDetail; + } + + /** + * Finishes the sign. + * + *

+ * For non local connectors this concludes the sign process, signs the + * document and returns the result. For local connectors this initializes the + * local sign process and redirects to following servlets. + *

+ * + * @param si + * The SessionInformation. + * @param request + * The servlet request for dispatching. + * @param response + * The servlet response for dispatching. + * @param context + * The servlet context for dispatching. + * @throws IOException + * f. e. + * @throws ServletException + * f. e. + * @throws PdfAsException + */ + public static void finishSign(SignSessionInformation si, HttpServletRequest request, HttpServletResponse response, ServletContext context) throws IOException, ServletException, PdfAsException + { + log.debug("finishSign:"); //$NON-NLS-1$ + PdfAs pdfAs = ApiHelper.getPdfAsFromContext(context); + PdfAsInternal pdfAsInternal = ApiHelper.getPdfAsInternalFromContext(context); + + // check if document is empty + if (si.sdi.getSignatureData() == null || si.sdi.getSignatureData().getLength() == 0) { + throw new PDFDocumentException(251, "Unable to extract and textual content."); + } + + log.debug("connector = " + si.connector); //$NON-NLS-1$ + if (LocalRequestHelper.isConnectorLocal(si.connector)) + { + log.debug("Connector is local -> dispatching to local processing."); //$NON-NLS-1$ + + String dispatch_to = LocalRequestHelper.processLocalSign(pdfAsInternal, si, request, response); + dispatch(request, response, dispatch_to, context); + return; + } + log.debug("Connector is not local -> finishing the sign."); //$NON-NLS-1$ + + ByteArrayDataSink data = new ByteArrayDataSink(); + si.signParameters.setOutput(data); + SignResult signResult = pdfAs.sign(si.signParameters, si.sdi); + si.signResult = signResult; + si.signedPdf = data.getData(); + +// PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode); +// Signator signator = SignatorFactory.createSignator(algorithm); +// +// log.debug("RequestURL = " + request.getRequestURL()); +// log.debug("ContextPath = " + request.getContextPath()); +// String host = request.getServerName(); + + // TODO TR: Web-Applikation verwendet in Loc-Ref-Variante ext. Referenz, um performanter zu sein; + // nachfolend auskommentieren, wenn anstatt SwA-Connector LocRef-Connector verwendet wird +// URL signature_data_URL = new URL(WebUtils.addJSessionID(LocalRequestHelper.getLocalContextAddress(request, response) + "/RetrieveSignatureData", request)); +// URL signature_data_URL = new URL(WebUtils.buildRetrieveSignatureDataURL(request, response)); +// String signature_data_url = response.encodeURL(signature_data_URL.toString()); +// +// Connector c = ConnectorChooser.chooseWebConnectorForSign(si.connector, si.type, signature_data_url); +// SignSignatureObject signSignatureObject = c.doSign(si.si.getSignatureData()); +// +// si.si.setSignSignatureObject(signSignatureObject); + +// si.output = TempDirHelper.createTempDataSink(si.filename + "_signed.pdf"); +// signator.finishSign(si.si, si.output); + + returnSignResponse(si, request, response); + log.debug("finishSign finished."); //$NON-NLS-1$ + + } + + /** + * Returns the data in the SignResult with proper content disposition. + * + * @param si + * SessionInformation. + * @param bs + * @parem request The servlet request. + * @param response + * The servlet response. + * @throws IOException + * The IO Exception. + */ + public static void returnSignResponse(SignSessionInformation si, HttpServletRequest request, HttpServletResponse response) throws IOException + { +// SignResult sign_result = si.sign_result; + + String file_name = formatFileNameForSignResult(si.filename, si.output.getMimeType()); + + // tzefferer: added condition + if (si.exappinf == null) + { + + // The name parameter is actually deprecated in favour of + // Content-Disposition filename + // Unfortunately Acrobat reader does recognize neither of these parameters + // with its inline save-as. It always takes the page name. + response.setContentType(si.output.getMimeType() + "; name=\"" + file_name + "\""); + if (si.download_inline) + { + response.addHeader("Content-Disposition", "inline; filename=\"" + file_name + "\""); + } + else + { + response.addHeader("Content-Disposition", "attachment; filename=\"" + file_name + "\""); + } + + IOUtils.write(si.signedPdf, response.getOutputStream()); +// TempDirHelper.writeDataSinkToHttpResponse(si.output, response); + //response.getOutputStream().write(sign_result.getData()); + + // tzefferer: added else-block + } + else + { + /** + * The following code handles an external invocation of pdf-as. External invocation is done by + * redirecting the user to the Sign-Servlet using the parameters defined in class + * at.knowcenter.wag.egov.egiz.web.FormFields. + * e.g. http://localhost:48080/pdf-as/Sign?preview=false&connector=bku&mode=textual&sig_type=SIGNATURBLOCK_DE&inline=false&filename=test.pdf&num-bytes=45916&pdf-url=http%3A%2F%2Flocalhost%3A8080%2Fmyapp%2FProvidePDF&pdf-id=1956507909008215134&invoke-app-url=https%3A%2F%2Flocalhost%3A8443%2Fmyapp%2FReturnSignedPDF&invoke-app-error-url=https%3A%2F%2Flocalhost%3A8443%2Fmyapp%2Fpdfaserror.do&session-id=9085B85B364BEC31E7D38047FE54577D&locale=de + */ + log.debug("External webapp invocation detected."); + byte [] signed_pdf = si.signedPdf; +// byte [] signed_pdf = null; +// if (si.output instanceof FileBasedDataSink) +// { +// FileBasedDataSink fbds = (FileBasedDataSink)si.output; +// signed_pdf = new byte [(int)fbds.getFile().length()]; +// FileInputStream fis = new FileInputStream(fbds.getFile()); +// fis.read(signed_pdf); +// fis.close(); +// } +// else +// { +// ByteArrayDataSink bads = (ByteArrayDataSink)si.output; +// signed_pdf = bads.getByteArray(); +// } + HttpSession session = request.getSession(); + + PDFContainer entry = new PDFContainer(signed_pdf, si.exappinf.pdf_id); + ProvidePDFServlet.signedDocuments.add(entry); + + // notify webapp... + String invoke_url = si.exappinf.invoke_url; + + String providePDFServlet = "ProvidePDF"; + String pdf_id = String.valueOf(si.exappinf.pdf_id); + String session_id = si.exappinf.session_id; + + log.debug("External application has to be notified. Building url from callback url \"" + invoke_url + "\"."); + + // build URL + int ind = invoke_url.indexOf("?"); + + // fixed by tknall: must not presume that invoke_url contains "?" + String sep = "&"; + if (ind == -1) { + ind = invoke_url.length(); + sep = "?"; + } + + String query = invoke_url.substring(0, ind) + ";jsessionid=" + session_id + invoke_url.substring(ind) + + sep + FormFields.FIELD_PDF_URL + "=" + providePDFServlet + "&" + FormFields.FIELD_PDF_ID + + "=" + pdf_id + "&" + FormFields.FIELD_FILE_LENGTH + "=" + signed_pdf.length + + "&" + FormFields.FIELD_PDFAS_SESSION_ID + "=" + session.getId(); + + /* + * Using the external web-interface of pdf-as (as described above) pdf-as should be run within + * an iframe. In case of a signature performed with a local citizen card software or with the + * server bku the result has to be provided outside the iframe. To break out of the iframe a + * helper jsp (redirect_to_parent) has to be used that redirects the user to the parent + * window. + */ + disableBrowserCacheForResponse(response); + if (Constants.SIGNATURE_DEVICE_BKU.equals(si.connector) || Constants.SIGNATURE_DEVICE_MOC.equals(si.connector)) { + log.debug("Pdf-as is supposed to run within an iframe."); + log.debug("Putting external application notify url (\"" + query + "\") in session (" + session.getId() + ") for later use."); + session.setAttribute(SessionAttributes.PARENT_WEBAPP_REDIRECT_URL, query); + String redirectHelper = response.encodeRedirectURL(request.getContextPath() + "/jsp/redirect_to_parent.jsp"); + + log.debug("Redirecting to " + redirectHelper); + log.debug("The browser will finally be redirected outside the iframe to " + query + " in order to notify the external application."); + + response.sendRedirect(redirectHelper); + + } else { + log.debug("Notifying external application by redirecting to \"" + query + "\"."); + response.sendRedirect(query); + } + + } + + } + + public static void disableBrowserCacheForResponse(HttpServletResponse response) { + log.debug("Disabling browser cache for HttpServletResponse."); + response.setHeader("Cache-Control", "no-cache"); + response.setHeader("Pragma","no-cache"); + response.setDateHeader("Expires", -1); + } + + /** + * The Mime Type for XML. + */ + public static final String XML_MIME_TYPE = "text/xml"; //$NON-NLS-1$ + + /** + * Formats the file name according to the SignResult. + * + * @param file_name + * The file name. + * @param sign_result + * The sign result. + * @return Returns the formatted file name. + */ + public static String formatFileNameForSignResult(String file_name, String mimeType) + { + String output = file_name + "_signed"; + if (mimeType.equals(XML_MIME_TYPE)) + { + output += ".xml"; + } + else + { + output += ".pdf"; + } + + return output; + } + + + public static void finishLocalSign(PdfAs pdfAs, PdfAsInternal pdfAsInternal, SignSessionInformation si) throws PdfAsException { + ByteArrayDataSink data = new ByteArrayDataSink(); + si.signParameters.setOutput(data); + + SignResult signResult = pdfAsInternal.finishLocalSign(pdfAs, si.signParameters, si.sdi, si.localBKUParams, si.xmlResponse); + si.signResult = signResult; + si.output = data; + si.outputAvailable = true; + si.signedPdf = data.getData(); + } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SigningTimeHelper.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SigningTimeHelper.java new file mode 100644 index 0000000..4837a70 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SigningTimeHelper.java @@ -0,0 +1,71 @@ +package at.gv.egiz.pdfas.web.helper; + +import java.util.Date; + +import org.apache.commons.lang.time.DateFormatUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; +import at.knowcenter.wag.egov.egiz.exceptions.SignatureException; + +/** + * This class deals with invalid signing times. + * @author tknall + */ +public final class SigningTimeHelper { + + private SigningTimeHelper() { + } + + private static Integer tolerance = null; + + /** + * The log. + */ + private final static Log LOG = LogFactory.getLog(SigningTimeHelper.class); + + private final static String FORMAT_UTC_DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'"; + + public static synchronized void checkSigningTimeAgainstHostTime(Date signingTime) throws SignatureException { + if (tolerance == null) { + try { + String toleranceString = WebSettingsReader.getInstance().getSigningTimeTolerance(); + tolerance = new Integer(Integer.parseInt(toleranceString)); + } catch (NumberFormatException e) { + LOG.warn("Invalid configuration key signingtimetolerance. Disabling signing time check."); + tolerance = new Integer(-1); + } catch (SettingsException e) { + LOG.warn("Invalid configuration key signingtimetolerance. Disabling signing time check."); + tolerance = new Integer(-1); + } + } + if (tolerance.intValue() == -1) { + return; + } + + // current time + Date currentTime = new Date(); + + // lower limit + Date lowerLimit = new Date(currentTime.getTime() - tolerance.intValue()*1000); + + // upper limit + Date upperLimit = new Date(currentTime.getTime() + tolerance.intValue()*1000); + + String signingTimeString = DateFormatUtils.formatUTC(signingTime, FORMAT_UTC_DATE_PATTERN); + + if (LOG.isDebugEnabled()) { + String lower = DateFormatUtils.formatUTC(lowerLimit, FORMAT_UTC_DATE_PATTERN); + String upper = DateFormatUtils.formatUTC(upperLimit, FORMAT_UTC_DATE_PATTERN); + LOG.debug("Checking if signing time " + signingTimeString + " is valid according to the given time frame [ " + lower + ", " + upper + " ]."); + } + + if (signingTime.before(lowerLimit) || signingTime.after(upperLimit)) { + throw new SignatureException(ErrorCode.INVALID_SIGNING_TIME, "The signing time " + signingTimeString + " is out of the given tolerance of " + tolerance.intValue() + " seconds."); + } + + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/WebSettingsReader.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/WebSettingsReader.java new file mode 100644 index 0000000..c7f6b7e --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/WebSettingsReader.java @@ -0,0 +1,210 @@ +package at.gv.egiz.pdfas.web.helper; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Properties; + +import org.apache.commons.lang.text.StrSubstitutor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.api.commons.Constants; +import at.gv.egiz.pdfas.api.exceptions.ConfigUtilsException; +import at.gv.egiz.pdfas.utils.ConfigUtils; +import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; + +/** + * + * @author exthex + * + */ +public class WebSettingsReader { + + /** + * The configuration key that replaces a dynamically generated retrieve signature data url. + */ + private final static String RETRIEVE_SIGNATURE_DATA_URL_OVERRIDE_KEY = "retrieve_signature_data_url_override"; + + private final static String SIGNING_TIME_TOLERANCE_KEY = "signing_time_tolerance"; + + private static final Log logger_ = LogFactory.getLog(WebSettingsReader.class); + + public static String RESOURCES_PATH = null; + + private static String TMP_PATH = null; + + private static String CONFIG_PATH; + + private static String CFG = "cfg"; + + private String WEB_CONFIG_FILE_DEFAULT_NAME = "pdf-as-web.properties"; + + public static synchronized void initialize(String work_dir) { + + String tmpDir = null; + + String defaultConfigDeployedTo = null; + // resolve work directory + // configuration explicitely given ? + if (work_dir == null) { + + // configuration via system property ? + logger_.debug("No configuration directory given. Looking for system property \"" + + Constants.CONFIG_DIR_SYSTEM_PROPERTY + "\"."); + work_dir = System.getProperty(Constants.CONFIG_DIR_SYSTEM_PROPERTY); + if (work_dir == null) { + + // configuration via user's home directory ? + logger_ + .debug("System property not set. Trying to locate configuration within the user's home directory."); + String userHome = System.getProperty("user.home"); + if (userHome == null || userHome.length() == 0) { + throw new RuntimeException("Unable to resolve user's home directory."); + } + work_dir = ConfigUtils.assertFileSeparator(userHome) + Constants.USERHOME_CONFIG_FOLDER; + try { + defaultConfigDeployedTo = ConfigUtils.deployDefaultConfiguration(work_dir, false); + } catch (ConfigUtilsException e) { + throw new RuntimeException(e); + } + if (defaultConfigDeployedTo != null) { + logger_.info("** Default configuration successfully deployed to \"" + + defaultConfigDeployedTo + "\" **"); + } else { + logger_ + .debug("Default configuration has NOT been deployed. Maybe the configuration already exists."); + } + } else { + logger_.debug("Configuration set by system property."); + tmpDir = work_dir; + } + } else { + logger_.debug("Configuration path explicitely set."); + } + File configdirFile = new File(StrSubstitutor.replaceSystemProperties(work_dir)); + try { + work_dir = ConfigUtils.assertFileSeparator(configdirFile.getCanonicalPath()); + } catch (IOException e) { + work_dir = ConfigUtils.assertFileSeparator(configdirFile.getPath()); + } + if (!configdirFile.isDirectory()) { + throw new IllegalArgumentException("The config directory \"" + work_dir + + "\" does not exist or is not a directory."); + } + + // resolve temporary dir + if (tmpDir == null) { + logger_ + .debug("Temporary directory not explicitely set. Looking for user's temp directory."); + tmpDir = System.getProperty("java.io.tmpdir"); + if (tmpDir == null) { + logger_ + .debug("Unable to resolve user's temporary directory. Assuming temporary directory located within config dir."); + tmpDir = work_dir; + } + } else { + logger_.debug("Temporary directory explicitely set."); + } + File tmpdirFile = new File(StrSubstitutor.replaceSystemProperties(ConfigUtils + .assertFileSeparator(tmpDir) + Constants.TEMP_DIR_NAME)); + try { + tmpDir = ConfigUtils.assertFileSeparator(tmpdirFile.getCanonicalPath()); + } catch (IOException e) { + tmpDir = ConfigUtils.assertFileSeparator(tmpdirFile.getPath()); + } + + RESOURCES_PATH = work_dir; + TMP_PATH = tmpDir; + File tmpFile = new File(TMP_PATH); + if (!tmpFile.exists()) + tmpFile.mkdirs(); + CONFIG_PATH = RESOURCES_PATH + CFG + System.getProperty("file.separator"); + + if (defaultConfigDeployedTo != null) { + logger_.debug("** Default configuration successfully deployed to \"" + + defaultConfigDeployedTo + "\" **"); + } + logger_.debug("Setting system property \"" + Constants.CONFIG_DIR_SYSTEM_PROPERTY + + "\" to \"" + configdirFile.getPath() + "\"."); + System.setProperty(Constants.CONFIG_DIR_SYSTEM_PROPERTY, configdirFile.getPath()); + } + + private static WebSettingsReader instance; + + /** + * + * @return + * @throws SettingsException + */ + public static synchronized WebSettingsReader getInstance() throws SettingsException { + if (instance == null) + instance = new WebSettingsReader(); + return instance; + } + + /** + * + */ + public static void clearTemporaryDirectory() { + File temp_dir = new File(TMP_PATH); + logger_.debug("Clearing temporary directory: " + temp_dir); + + if (!temp_dir.exists()) + { + return; + } + + File[] files = temp_dir.listFiles(); + for (int i = 0; i < files.length; i++) + { + // added by tknall: do not try to remove svn-metadata + if (files[i].getName().endsWith(".svn")) { + continue; + } + logger_.debug(" Clearing temporary file: " + files[i]); + boolean delete_success = files[i].delete(); + if (!delete_success) + { + logger_.error("Couldn't delete the temporary file: " + files[i]); + } + } + } + + /** + * + * @return + */ + public static File getTemporaryDirectory() { + return new File(TMP_PATH); + } + + private Properties props; + + private WebSettingsReader() throws SettingsException { + String settingsFile = CONFIG_PATH + WEB_CONFIG_FILE_DEFAULT_NAME; + props = new Properties(); + try { + props.load(new FileInputStream(settingsFile)); + }catch(IOException ioe){ + throw new SettingsException("", ioe); + } + } + + /** + * + * @return + */ + public String getSigningTimeTolerance() { + return props.getProperty(SIGNING_TIME_TOLERANCE_KEY); + } + + /** + * + * @return + */ + public String getRetrieveSignatureDataURLOverride() { + return props.getProperty(RETRIEVE_SIGNATURE_DATA_URL_OVERRIDE_KEY); + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/WebUtils.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/WebUtils.java new file mode 100644 index 0000000..61d694c --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/WebUtils.java @@ -0,0 +1,92 @@ +package at.gv.egiz.pdfas.web.helper; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; + +/** + * @author tknall + */ +public final class WebUtils { + + private WebUtils() { + } + + /** + * The log. + */ + private final static Log LOG = LogFactory.getLog(WebUtils.class); + + /** + * Unlike {@link HttpServletResponse#encodeURL(String)} that adds only a + * {@code JSESSIONID} entry to the given url if needed, this method always + * adds the session id (except if already present within the url. + * + * @param url + * The given url. + * @param session + * The {@link HttpSession}. + * @return The given url plus a session id. + */ + public static String addJSessionID(String url, HttpSession session) { + if (url == null) { + return null; + } + if (!StringUtils.containsIgnoreCase(url, ";jsessionid=")) { + url = url + ";jsessionid=" + session.getId(); + LOG.debug("Adding jsessionid " + session.getId()); + } else { + LOG.debug("No need to add a jsessionid."); + } + LOG.debug("Returning url " + url); + return url; + } + + /** + * Unlike {@link HttpServletResponse#encodeURL(String)} that adds only a + * {@code JSESSIONID} entry to the given url if needed, this method always + * adds the session id (except if already present within the url. + * + * @param url + * The given url. + * @param request + * The {@link HttpServletRequest}. + * @return The given url plus a session id. + */ + public static String addJSessionID(String url, HttpServletRequest request) { + return addJSessionID(url, request.getSession()); + } + + /** + * Either dynamically creates locref content url or uses a url provides by the pdf-as + * configuration (key {@code retrieve_signature_data_url_override}). + * @param request The {@link HttpServletRequest}. + * @param response The {@link HttpServletResponse}. + * @return The retrieve signature data url. + */ + public static String buildRetrieveSignatureDataURL(HttpServletRequest request, HttpServletResponse response) { + String override = null; + LOG.debug("Building retrieve signature data url."); + try { + override = WebSettingsReader.getInstance().getRetrieveSignatureDataURLOverride(); + } catch (SettingsException e) { + LOG.info(e); + } + String result; + if (override == null) { + result = WebUtils.addJSessionID(LocalRequestHelper.getLocalContextAddress(request, response) + "/RetrieveSignatureData", request); + } else { + LOG.debug("Override url found: " + override); + result = WebUtils.addJSessionID(override, request); + } + LOG.debug("RetrieveSignatureDataURL = " + result); + return result; + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/i18n/LanguageDecoratorMapper.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/i18n/LanguageDecoratorMapper.java new file mode 100644 index 0000000..42e6b03 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/i18n/LanguageDecoratorMapper.java @@ -0,0 +1,125 @@ +package at.gv.egiz.pdfas.web.i18n; + +import java.io.File; +import java.util.Locale; +import java.util.Properties; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; + +import com.opensymphony.module.sitemesh.Config; +import com.opensymphony.module.sitemesh.Decorator; +import com.opensymphony.module.sitemesh.DecoratorMapper; +import com.opensymphony.module.sitemesh.Page; +import com.opensymphony.module.sitemesh.mapper.AbstractDecoratorMapper; +import com.opensymphony.module.sitemesh.mapper.DefaultDecorator; + +public class LanguageDecoratorMapper extends AbstractDecoratorMapper { + + + private String decoratorParameter = null; + + private static final Logger LOG = Logger.getLogger(LanguageDecoratorMapper.class); + + public void init(Config config, Properties properties, DecoratorMapper parent) throws InstantiationException { + super.init(config, properties, parent); + } + + public static Object getFirstNotNull(Object[] objects) { + if (objects == null) { + return null; + } + for (int i = 0; i < objects.length; i++) { + if (objects[i] != null) { + return objects[i]; + } + } + return null; + } + + public static Locale getLocale(HttpServletRequest request, String decoratorParameter) { + Locale locale = null; + HttpSession session = request.getSession(); + + LOG.trace("Looking for locale in session (ID=" + session.getId() + ")."); + locale = (Locale) session.getAttribute(LocaleParamFilter.LOCALE_SESSION_KEY); + if (locale == null) { + LOG.debug("Unable to find locale in session. Trying to create new locale based on Accept-Language header entry."); + String acceptLanguage = request.getHeader("Accept-Language"); + if (acceptLanguage != null) { + LOG.trace("Accept-Language header entry: " + acceptLanguage); + } else { + LOG.trace("No header entry found."); + } + if (acceptLanguage != null && acceptLanguage.length() >= 2) { + locale = new Locale(acceptLanguage.substring(0, 2)); + LOG.debug("New Locale created: " + locale); + LOG.trace("Setting language to " + locale.getDisplayLanguage() + "."); + session.setAttribute(LocaleParamFilter.LOCALE_SESSION_KEY, locale); + } + } else { + LOG.trace("Locale found: " + locale); + } + + return locale; + } + + public Decorator getDecorator(HttpServletRequest request, Page page) { + LOG.trace("SiteMesh language resource decorator mapper invoked."); + + try { + Decorator result = null; + final Decorator d = super.getDecorator(request, page); + Locale locale = getLocale(request, this.decoratorParameter); + + String path; + if (locale != null) { + path = modifyPath(d.getPage(), locale.getLanguage()); + } else { + path = d.getPage(); + } + + File decFile = new File(config.getServletContext().getRealPath(path)); + + LOG.trace("Looking for decorator \"" + path + "\"."); + if (decFile.isFile()) { + result = new DefaultDecorator(d.getName(), path, null) { + public String getInitParameter(String paramName) { + return d.getInitParameter(paramName); + } + }; + } + + if (result != null) { + LOG.trace("Decorator found (\"" + result.getName() + "\", \"" + getFirstNotNull(new Object[] { result.getURIPath(), result.getPage(), ""}) + "\")."); + return result; + } else { + LOG.trace("No decorator found. Delegating to super class."); + result = super.getDecorator(request, page); + if (result != null) { + LOG.trace("Super class returned decorator (\"" + result.getName() + "\", \"" + getFirstNotNull(new Object[] { result.getURIPath(), result.getPage(), ""}) + "\")."); + } else { + LOG.trace("Super class did not return a decorator."); + } + return result; + } + } catch (NullPointerException e) { + return super.getDecorator(request, page); + } + } + + private static String modifyPath(String path, String ext) { + if (ext == null || ext.length() == 0) { + return path; + } + int dot = path.lastIndexOf('.'); + if (dot > -1) { + return path.substring(0, dot) + '-' + ext + path.substring(dot); + } else { + return path + '-' + ext; + } + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/i18n/LocaleParamFilter.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/i18n/LocaleParamFilter.java new file mode 100644 index 0000000..598b23b --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/i18n/LocaleParamFilter.java @@ -0,0 +1,96 @@ +package at.gv.egiz.pdfas.web.i18n; + +import java.io.IOException; +import java.util.Locale; +import java.util.StringTokenizer; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.commons.lang.LocaleUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +public class LocaleParamFilter implements Filter { + + private static final Logger LOG = Logger.getLogger(LocaleParamFilter.class); + public static final String LOCALE_SESSION_KEY = "at.gv.egiz.pdfas.web.i18n:currentLocale"; + public static final String LOCALE_PARAM_KEY = "locale"; + + public void destroy() { + } + + public static String normalizeLocaleString(String localeString) { + if (localeString == null) { + return null; + } + int jsessionIdIndex = localeString.toLowerCase().indexOf(";jsessionid"); + if (jsessionIdIndex != -1) { + localeString = localeString.substring(0, jsessionIdIndex); + } + StringTokenizer tokenizer = new StringTokenizer(localeString, "_", false); + StringBuffer buffer = new StringBuffer(); + int index = 0; + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + switch (++index) { + case 1: + buffer.append(token.toLowerCase()); + break; + case 2: + buffer.append(token.toUpperCase()); + break; + default: + buffer.append(token); + break; + } + if (tokenizer.hasMoreTokens()) { + buffer.append("_"); + } + } + return buffer.toString(); + } + + public static Locale getLocale(HttpServletRequest request) { + Locale locale = null; + HttpSession session = request.getSession(); + + LOG.trace("Looking for locale parameter \"" + LOCALE_PARAM_KEY + "\"."); + String language = request.getParameter(LOCALE_PARAM_KEY); + if (!StringUtils.isEmpty(language)) { + LOG.debug("Locale parameter \"" + language + "\" found."); + String code = normalizeLocaleString(language.trim()); + LOG.debug("Normalizing locale -> " + code); + try { + locale = LocaleUtils.toLocale(code); + LOG.info("Setting locale flag in session (ID=" + session.getId() + ") to \"" + locale.toString() + "\"."); + session.setAttribute(LOCALE_SESSION_KEY, locale); + } catch (IllegalArgumentException e) { + LOG.error("Locale \"" + code + "\" is not valid. Flag will not be set."); + } + } else { + LOG.trace("No locale parameter found."); + } + + return locale; + } + + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + + LOG.trace("LocaleParamFilter invoked."); + getLocale(request); + + filterChain.doFilter(servletRequest, servletResponse); + } + + public void init(FilterConfig filterConfig) throws ServletException { + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/io/ByteArrayDataSink.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/io/ByteArrayDataSink.java new file mode 100644 index 0000000..4bdb724 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/io/ByteArrayDataSink.java @@ -0,0 +1,49 @@ +package at.gv.egiz.pdfas.web.io; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import at.gv.egiz.pdfas.api.io.DataSink; + +public class ByteArrayDataSink implements DataSink { + + private ByteArrayOutputStream baos; + private String mimeType; + private String characterEncoding; + + public OutputStream createOutputStream(String mimeType) throws IOException { + this.mimeType = mimeType; + baos = new ByteArrayOutputStream(); + return baos; + } + + public OutputStream createOutputStream(String mimeType, String characterEncoding) + throws IOException { + this.mimeType = mimeType; + this.characterEncoding = characterEncoding; + baos = new ByteArrayOutputStream(); + return baos; + } + + public byte[] getData() { + return baos.toByteArray(); + } + + public String getMimeType() { + return this.mimeType; + } + + public String getCharacterEncoding() { + return this.characterEncoding; + } + + public void setMimeType(String mimeType) { + this.mimeType = mimeType; + } + + public void setCharacterEncoding(String characterEncoding) { + this.characterEncoding = characterEncoding; + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/io/ByteArrayPdfDataSource.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/io/ByteArrayPdfDataSource.java new file mode 100644 index 0000000..ae53397 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/io/ByteArrayPdfDataSource.java @@ -0,0 +1,41 @@ +package at.gv.egiz.pdfas.web.io; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import at.gv.egiz.pdfas.api.io.DataSource; + +/** + * + * @author exthex + * + */ +public class ByteArrayPdfDataSource implements DataSource { + + private byte[] data; + + public ByteArrayPdfDataSource(byte[] data) { + this.data = data; + } + + public InputStream createInputStream() { + return new ByteArrayInputStream(this.data); + } + + public int getLength() { + return this.data.length; + } + + public byte[] getAsByteArray() { + return this.data; + } + + public String getMimeType() { + return "application/pdf"; + } + + public String getCharacterEncoding() { + return null; + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/io/TextDataSource.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/io/TextDataSource.java new file mode 100644 index 0000000..de5c7a8 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/io/TextDataSource.java @@ -0,0 +1,50 @@ +package at.gv.egiz.pdfas.web.io; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; + +import at.gv.egiz.pdfas.api.io.DataSource; + +/** + * + * @author exthex + * + */ +public class TextDataSource implements DataSource { + + private String text; + + public TextDataSource(String text) { + this.text = text; + } + + public InputStream createInputStream() { + try { + return new ByteArrayInputStream(text.getBytes("UTF-8")); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + public int getLength() { + return 0; + } + + public byte[] getAsByteArray() { + try{ + return text.getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + public String getMimeType() { + return "text/plain"; + } + + public String getCharacterEncoding() { + return "UTF-8"; + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/itext/IText.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/itext/IText.java new file mode 100644 index 0000000..7175991 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/itext/IText.java @@ -0,0 +1,111 @@ +package at.gv.egiz.pdfas.web.itext; + +import java.awt.color.ICC_Profile; +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.ByteArrayOutputStream; +import org.apache.log4j.Logger; + +import com.lowagie.text.Document; +import com.lowagie.text.DocumentException; +import com.lowagie.text.Font; +import com.lowagie.text.PageSize; +import com.lowagie.text.Paragraph; +import com.lowagie.text.Rectangle; +import com.lowagie.text.pdf.BaseFont; +import com.lowagie.text.pdf.PdfArray; +import com.lowagie.text.pdf.PdfDictionary; +import com.lowagie.text.pdf.PdfICCBased; +import com.lowagie.text.pdf.PdfName; +import com.lowagie.text.pdf.PdfString; +import com.lowagie.text.pdf.PdfWriter; + +public final class IText { + + private IText() { + } + + private static final Logger LOG = Logger.getLogger(IText.class); + + private static final Font DEFAULT_FONT = new Font(Font.HELVETICA, 12, Font.NORMAL); + private static final String DEFAULT_TTF_FONT_RESOURCE = "DejaVuSansCondensed.ttf"; + private static final String DEFAULT_ICC_PROFILE_RESOURCE = "srgb.profile"; + private static final Rectangle DEFAULT_PAGE_SIZE = PageSize.A4; + private static final int[] DEFAULT_MARGINS_MM = { 25, 25, 25, 25 }; // top, right, bottom, left + public static final String DEFAULT_FILENAME = "text"; + + private static Font DEFAULT_TTF_FONT; + private static PdfICCBased DEFAULT_ICC_COLOR_SPACE; + + static { + try { + byte[] ttfFontData = IOUtils.toByteArray(IText.class.getResourceAsStream(DEFAULT_TTF_FONT_RESOURCE)); + DEFAULT_TTF_FONT = new Font(BaseFont.createFont(DEFAULT_TTF_FONT_RESOURCE, BaseFont.WINANSI, true, true, ttfFontData, null)); + } catch (Exception e) { + LOG.error(e); + DEFAULT_TTF_FONT = DEFAULT_FONT; + } + try { + byte[] iccData = IOUtils.toByteArray(IText.class.getResourceAsStream(DEFAULT_ICC_PROFILE_RESOURCE)); + DEFAULT_ICC_COLOR_SPACE = new PdfICCBased(ICC_Profile.getInstance(iccData)); + DEFAULT_ICC_COLOR_SPACE.remove(PdfName.ALTERNATE); + } catch (Exception e) { + LOG.error(e); + DEFAULT_ICC_COLOR_SPACE = null; + } + } + + public static byte[] createPDF(String content, boolean pdfa) throws DocumentException, IOException { + ByteArrayOutputStream baOut = new ByteArrayOutputStream(); + createPDF(content, pdfa, baOut); + return baOut.toByteArray(); + } + + public static byte[] createPDF(String content) throws DocumentException, IOException { + return createPDF(content, false); + } + + + private static void addContent(Document document, boolean pdfa, String content) throws DocumentException { + Paragraph p = new Paragraph(content, pdfa ? DEFAULT_TTF_FONT : DEFAULT_FONT); + document.add(p); + } + public static void createPDF(String content, OutputStream outputStream) throws DocumentException, IOException { + createPDF(content, false, outputStream); + } + + public static void createPDF(String content, boolean pdfa, OutputStream outputStream) throws DocumentException, IOException { + final float factor = (float) 72 / (float) 25.4; + Document document = new Document( + DEFAULT_PAGE_SIZE, + (float) DEFAULT_MARGINS_MM[3] * factor, // left + (float) DEFAULT_MARGINS_MM[1] * factor, // right + (float) DEFAULT_MARGINS_MM[0] * factor, // top + (float) DEFAULT_MARGINS_MM[2] * factor // bottom + ); + + PdfWriter pdfWriter = PdfWriter.getInstance(document, outputStream); + if (pdfa) { + pdfWriter.setPDFXConformance(PdfWriter.PDFA1B); + } + document.open(); + if (pdfa) { + PdfDictionary pdfOutputIntent = new PdfDictionary(PdfName.OUTPUTINTENT); + pdfOutputIntent.put(PdfName.OUTPUTCONDITIONIDENTIFIER, new PdfString("sRGB IEC61966-2.1")); + pdfOutputIntent.put(PdfName.INFO, new PdfString("sRGB IEC61966-2.1")); + pdfOutputIntent.put(PdfName.S, PdfName.GTS_PDFA1); + if (DEFAULT_ICC_COLOR_SPACE != null) { + pdfOutputIntent.put(PdfName.DESTOUTPUTPROFILE, pdfWriter.addToBody(DEFAULT_ICC_COLOR_SPACE).getIndirectReference()); + } + pdfWriter.getExtraCatalog().put(PdfName.OUTPUTINTENTS, new PdfArray(pdfOutputIntent)); + } + addContent(document, pdfa, content); + if (pdfa) { + pdfWriter.createXmpMetadata(); + } + document.close(); + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/AsynchronousDataResponder.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/AsynchronousDataResponder.java new file mode 100644 index 0000000..26f1670 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/AsynchronousDataResponder.java @@ -0,0 +1,157 @@ +/** + * 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: AsynchronousDataResponder.java,v 1.3 2006/08/30 14:02:35 wprinz Exp $ + */ +package at.gv.egiz.pdfas.web.servlets; + +import javax.servlet.http.HttpServlet; + +/** + * Servlet that responds to the data post requests of the local service (e.g. + * BKU). + * + * @deprecated + * + * @author wprinz + */ +public class AsynchronousDataResponder extends HttpServlet +{ + + /** + * SVUID. + */ + private static final long serialVersionUID = -4992297156381763174L; + +// /** +// * The logger definition. +// */ +// private static final Logger logger_ = ConfigLogger.getLogger(AsynchronousDataResponder.class); +// +// protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException +// { +// logger_.debug("AsyncDataResp GET REQUEST."); +// super.doGet(arg0, arg1); +// } +// +// protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException +// { +// logger_.debug("AsyncDataResp !!!!!!!!!!!!!!!!!!!!!!"); +// +// HttpSession session = request.getSession(false); +// if (session == null) +// { +// throw new ServletException("There is no session associated with this request."); +// } +// +// // String session_id_string = request.getParameter("session"); +// // if (session_id_string == null) +// // { +// // throw new ServletException("The session parameter is missing."); +// // } +// +// SessionInformation si = (SessionInformation) session.getAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION); +// // long session_id = Long.parseLong(session_id_string); +// // SessionInformation si = SessionTable.get(session_id); +// if (si == null) +// { +// throw new ServletException("The session is not found or no longer valid."); +// } +// +// // InputStream is = request.getInputStream(); +// // byte [] data = new byte[request.getContentLength()]; +// // is.read(data); +// // is.close(); +// // String enc = request.getCharacterEncoding(); +// // String ct = request.getContentType(); +// // Enumeration enum = request.getHeaderNames(); +// // +// // String dat = new String(data, "US-ASCII"); +// // // dat looks like: XMLResponse=blablabla ... +// // // so the actual XMLResponse begins after the = +// // String resp = URLDecoder.decode(dat, "UTF-8"); +// +// logger_.debug("Answer from local service: content-type = '" + request.getContentType() + "', character encoding = '" + request.getCharacterEncoding() + "'"); +// +// // .getParameter will use the character encoding specified by the +// // content-type header. +// // Unfortunately BKU forgets to specify a chatacter encoding. +// // Therefor, .getParameter will assume US-ASCII or something. +// // ==> we explicitely set UTF-8 +// if (request.getCharacterEncoding() == null) +// { +// request.setCharacterEncoding("UTF-8"); +// logger_.debug(" no character encoding specified - set to UTF-8"); +// } +// +// logger_.debug("AsyncDataResponder: si.current_operation = " + si.current_operation); +// +// String resp_string = request.getParameter("XMLResponse"); +// if (resp_string == null) +// { +// logger_.debug("response String is null => trying multipart form"); +// +// DiskFileItemFactory fif = new DiskFileItemFactory(); +// fif.setRepository(SettingsReader.getTemporaryDirectory()); +// ServletFileUpload sfu = new ServletFileUpload(fif); +// +// try +// { +// List items = sfu.parseRequest(request); +// +// for (int i = 0; i < items.size(); i++) +// { +// FileItem item = (FileItem) items.get(i); +// logger_.debug("item = " + item.getFieldName()); +// +// if (item.getFieldName().equals("XMLResponse")) +// { +// resp_string = item.getString("UTF-8"); +// } +// } +// } +// catch (FileUploadException e) +// { +// throw new ServletException("File Upload exception. cannot parse POST data"); +// } +// +// } +// +// // TODO hotfix - already deprecated +// if (logger_.isDebugEnabled()) +// { +// Enumeration header_names = request.getHeaderNames(); +// while (header_names.hasMoreElements()) +// { +// String header_name = (String)header_names.nextElement(); +// String header_value = request.getHeader(header_name); +// logger_.debug("header: name = " + header_name + ", value = " +header_value); +// } +// } +// String user_agent = request.getHeader("User-Agent"); +// logger_.debug("User-Agent header = " + user_agent); +// Properties response_properties = new Properties(); +// BKUPostConnection.parseBKUVersion(user_agent, response_properties); +// response_properties.setProperty("response_string", resp_string); +// si.response_properties[si.current_operation] = response_properties; //request.getParameter("XMLResponse"); +// //logger_.debug("AsyncDataResponder: si.response_string[si.current_operation] = " + si.response_string[si.current_operation]); +// +// si.current_operation++; +// +// si.finished = true; +// +// LocalRequestHelper.formatBKUOkResponse(response); +// } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/AsynchronousRedirectResponder.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/AsynchronousRedirectResponder.java new file mode 100644 index 0000000..80078ed --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/AsynchronousRedirectResponder.java @@ -0,0 +1,184 @@ +/** + * 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: AsynchronousRedirectResponder.java,v 1.4 2006/10/11 07:39:13 wprinz Exp $ + */ +package at.gv.egiz.pdfas.web.servlets; + +import javax.servlet.http.HttpServlet; + +/** + * Servlet that responds to the redirect requests of the local service (e.g. + * BKU). + * + * @deprecated remove this + * + * @author wprinz + */ +public class AsynchronousRedirectResponder extends HttpServlet +{ + + /** + * SVUID. + */ + private static final long serialVersionUID = -682360466333727236L; + +// /** +// * The logger definition. +// */ +// private static final Logger logger_ = ConfigLogger.getLogger(AsynchronousRedirectResponder.class); +// +// protected void dispatch(HttpServletRequest request, +// HttpServletResponse response, String resource) throws ServletException, IOException +// { +// response.setContentType("text/html"); +// response.setCharacterEncoding("UTF-8"); +// +// RequestDispatcher disp = getServletContext().getRequestDispatcher(resource); +// disp.forward(request, response); +// } +// +// protected void dispatchToResults(List results, HttpServletRequest request, +// HttpServletResponse response) throws ServletException, IOException +// { +// request.setAttribute("results", results); +// dispatch(request, response, "/jsp/results.jsp"); +// } +// +// protected void dispatchToRedirectRefreshPage (HttpServletRequest request, +// HttpServletResponse response, String refresh_url) throws ServletException, IOException +// { +// request.setAttribute("refresh_url", refresh_url); +// dispatch(request, response, LocalRequestHelper.REDIRECT_REFRESH_PAGE_JSP); +// } +// +// protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException +// { +// logger_.debug("AsyncRedirResp"); +// +// SessionInformation si = null; +// +// HttpSession session = null; +// try +// { +// session = request.getSession(false); +// //String session_id_string = request.getParameter("session"); +// if (session == null) +// { +// throw new ErrorCodeException(600, "The session is missing."); +// } +// +// si = (SessionInformation) session.getAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION); +//// long session_id = Long.parseLong(session_id_string); +//// si = SessionTable.get(session_id); +// if (si == null) +// { +// throw new ErrorCodeException(600, "The session is not found or is no longer valid."); +// } +// +// } +// catch (PresentableException e) +// { +// e.printStackTrace(); +// SignServlet.prepareDispatchToErrorPage(e, request); +// dispatch(request, response, "/jsp/error.jsp"); +// +// return; +// } +// +// try +// { +// if (si.finished == false) +// { +// String url = request.getRequestURL().toString(); +// logger_.debug("RequestURL = " + url); +// String refresh_url = response.encodeURL(url); +// logger_.debug("RefreshURL = " + refresh_url); +// dispatchToRedirectRefreshPage(request, response, refresh_url); +// return; +// } +// +// // si.finished is true, but maybe there are more requests to process. +// if (si.current_operation < si.requests.length) +// { +// si.finished = false; +// +// LocalRequestHelper.prepareDispatchToLocalConnectionPage(si.requests[si.current_operation], request, response); +// dispatch(request, response, LocalRequestHelper.LOCAL_CONNECTION_PAGE_JSP); +// return; +// } +// +// // all requests have been carried out. +// +// BKUConnector local_conn = (BKUConnector) ConnectorFactory.createConnector(si.connector); +// +// if (si.application.equals("verify")) +// { +// List results = new ArrayList(); +// +// for (int i = 0; i < si.response_properties.length; i++) +// { +// SignatureResponse sig_resp = local_conn.analyzeVerifyResponse(si.response_properties[i]); +// results.add(sig_resp); +// } +// +// dispatchToResults(results, request, response); +// } +// else +// { +// //logger_.debug("AsyncRedirResponder: si.response_string[0] = " + si.response_string[0]); +// logger_.debug("AsyncRedirResponder: si.current_op = " + si.current_operation); +// +// // The response string must not be null here - otherwise finished mustn't have been set! +//// if (si.response_string[0] == null) +//// { +//// String url = request.getRequestURL().toString(); +//// logger_.debug("RequestURL = " + url); +//// String refresh_url = response.encodeURL(url); +//// logger_.debug("RefreshURL = " + refresh_url); +//// dispatchToRedirectRefreshPage(request, response, refresh_url); +//// return ; +//// } +// +// // A download blocker may have blocked the first download. +// // So, if the user asks for the document a second time and the sign_result +// // has already been computed - don't recompute it. +// if (si.sign_result == null) +// { +// // refactor WEB +// si.iui.signed_signature_object = null; //local_conn.analyzeSignResponse(si.response_properties[0], si.type); +// +// PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode); +// Signator signator = SignatorFactory.createSignator(algorithm); +// +// si.sign_result = signator.finishSign(si.iui); +// } +// +// SignServlet.returnSignResponse(si, response); +// } +// +// } +// catch (PresentableException e) +// { +// session.removeAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION); +// //SessionTable.remove(si.session_id); +// +// e.printStackTrace(); +// SignServlet.prepareDispatchToErrorPage(e, request); +// dispatch(request, response, "/jsp/error.jsp"); +// } +// +// } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java new file mode 100644 index 0000000..2f6a76c --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java @@ -0,0 +1,390 @@ +/** + * + */ +package at.gv.egiz.pdfas.web.servlets; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.util.ArrayList; +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.FileItemFactory; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.api.PdfAs; +import at.gv.egiz.pdfas.api.commons.Constants; +import at.gv.egiz.pdfas.api.commons.SignatureInformation; +import at.gv.egiz.pdfas.api.exceptions.PdfAsException; +import at.gv.egiz.pdfas.api.internal.LocalBKUParams; +import at.gv.egiz.pdfas.api.internal.PdfAsInternal; +import at.gv.egiz.pdfas.api.verify.VerifyResult; +import at.gv.egiz.pdfas.api.verify.VerifyResults; +import at.gv.egiz.pdfas.web.LocalRequest; +import at.gv.egiz.pdfas.web.helper.ApiHelper; +import at.gv.egiz.pdfas.web.helper.LocalRequestHelper; +import at.gv.egiz.pdfas.web.helper.SessionHelper; +import at.gv.egiz.pdfas.web.helper.SignServletHelper; +import at.gv.egiz.pdfas.web.helper.SigningTimeHelper; +import at.gv.egiz.pdfas.web.session.SessionAttributes; +import at.gv.egiz.pdfas.web.session.SignSessionInformation; +import at.gv.egiz.pdfas.web.session.VerifySessionInformation; +import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; +import at.knowcenter.wag.egov.egiz.exceptions.SignatureException; + +/** + * @author wprinz + * + */ +public class DataURLServlet extends HttpServlet +{ + + /** + * SVUID. + */ + private static final long serialVersionUID = -5846618335843762752L; + + /** + * The log. + */ + private static Log log = LogFactory.getLog(DataURLServlet.class); + + 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); + } + + protected void dispatchToResults(VerifyResults results, HttpServletRequest request, + HttpServletResponse response, String backToListURL) throws ServletException, IOException + { + request.setAttribute("results", results); + request.setAttribute("btlurl", backToListURL); + dispatch(request, response, "/jsp/results.jsp"); + } + + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + this.doPost(req, resp); + } + + private static void temporaryRedirect(String redirectURL, HttpServletResponse response) throws IOException { + String encodedRedirect = response.encodeRedirectURL(redirectURL); + response.addHeader("Location", encodedRedirect); + response.setContentType("text/xml"); + response.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT); + String nop = ""; + PrintWriter pw = response.getWriter(); + response.setCharacterEncoding("UTF-8"); + response.setContentLength(nop.getBytes("UTF-8").length); + log.debug("Redirecting via NullOperationRequest to " + encodedRedirect + "."); + pw.println(nop); + pw.flush(); + pw.close(); + } + +/** + * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + log.debug("Data URL is accessed."); //$NON-NLS-1$ + + try + { + Object sessionObject = SessionHelper.getSession(request); + + // obsolete since EncodingFilter is set in web.xml + checkRequestCharacterEncoding(request); + + if (sessionObject instanceof SignSessionInformation) + { + SignSessionInformation si = (SignSessionInformation)sessionObject; + processSign(request, response, si); + } + else + { + VerifySessionInformation si = (VerifySessionInformation) sessionObject; + processVerify(request, response, si); + } + + } + catch (PdfAsException e) + { + log.error(e.getMessage(), e); + SignServlet.prepareDispatchToErrorPage(e, request); + dispatch(request, response, "/jsp/error.jsp"); + } + + log.debug("DataURL access finished."); //$NON-NLS-1$ + } + + protected void checkRequestCharacterEncoding(HttpServletRequest request) throws UnsupportedEncodingException + { + if (request.getCharacterEncoding() == null || request.getCharacterEncoding().length() <= 0) //$NON-NLS-1$ + { + log.info("The BKU didn't set a character encoding for the request."); //$NON-NLS-1$ + + log.info("Manually setting character encoding to UTF-8"); //$NON-NLS-1$ + request.setCharacterEncoding("UTF-8"); //$NON-NLS-1$ + } + } + + protected boolean isNullResponse(String xml_response) + { + return xml_response != null && xml_response.indexOf("NullOperationResponse") != -1; + } + + private static String retrieveXMLResponse(HttpServletRequest request) throws ServletException { + log.debug("Trying to fetch XMLResponse..."); + String xml_response = null; + if (ServletFileUpload.isMultipartContent(request)) { + log.debug("Response is multipart."); + FileItemFactory factory = new DiskFileItemFactory(); + ServletFileUpload upload = new ServletFileUpload(factory); + try { + List items = upload.parseRequest(request); + Iterator iter = items.iterator(); + while (iter.hasNext()) { + FileItem item = (FileItem) iter.next(); + if (item.isFormField() && "XMLResponse".equals(item.getFieldName())) { + log.debug("XMLResponse part found."); + xml_response = item.getString(); + break; + } + } + } catch (FileUploadException e) { + throw new ServletException(e); + } + } else { + xml_response = request.getParameter("XMLResponse"); + } + log.debug("XMLResponse = " + xml_response); + return xml_response; + } + + protected void processSign(HttpServletRequest request, HttpServletResponse response, SignSessionInformation si) throws ServletException, IOException, PdfAsException + { + log.trace("processSign"); + + String xml_response = retrieveXMLResponse(request); + + PdfAsInternal pdfAsInternal = ApiHelper.getPdfAsInternalFromContext(getServletContext()); + + String server = request.getHeader("server"); + String userAgent = request.getHeader("user-agent"); + String signatureLayout = request.getHeader(Constants.BKU_HEADER_SIGNATURE_LAYOUT); + LocalBKUParams bkuParams = new LocalBKUParams(server, userAgent, signatureLayout); + si.localBKUParams = bkuParams; + + pdfAsInternal.verifyBKUSupport(bkuParams); + +// Properties response_properties = BKUHelper.getBKUProperties(request); +// +// String bkuIdentifier = BKUHelper.getBKUIdentifier(response_properties); +// log.debug("BKU identifier: \"" + bkuIdentifier + "\""); +// +// try { +// SignatureLayoutHandlerFactory.verifyBKUSupport(bkuIdentifier); +// } catch (SettingsException e) { +// throw new ConnectorException(e.getErrorCode(), e.getMessage()); +// } + + if (isNullResponse(xml_response)) + { + log.debug("Received a NullOperationResponse -> answering with the first request."); //$NON-NLS-1$ + + assert si.outputAvailable == false; + assert si.xmlResponse == null; + + log.debug("There are still requests to be performed -> answering with request."); //$NON-NLS-1$ + + LocalRequest local_request = si.localRequest; + + String request_string = local_request.getRequestString(); + + log.debug("request = " + request_string); + response.setContentType("text/xml"); + response.setCharacterEncoding("UTF-8"); + response.getWriter().println(request_string); + } + else if (xml_response != null) + { + log.debug("Received a normal response -> storing the response."); //$NON-NLS-1$ + +// response_properties.setProperty(BKUPostConnection.RESPONSE_STRING_KEY, xml_response); +// +// si.response_properties = response_properties; + si.xmlResponse = xml_response; + + log.debug("All requests have been processed -> processing the responses."); //$NON-NLS-1$ + + // Sign + + if (!si.outputAvailable) + { + PdfAs pdfAs = ApiHelper.getPdfAsFromContext(getServletContext()); + SignServletHelper.finishLocalSign(pdfAs, pdfAsInternal, si); + SigningTimeHelper.checkSigningTimeAgainstHostTime(si.sdi.getSignDate()); +// LocalConnector c = ConnectorChooser.chooseLocalConnectorForSign(si.connector, si.type, "loc ref content not needed here"); //$NON-NLS-1$ +// +// si.si.setSignSignatureObject(c.analyzeSignResponse(si.response_properties)); +// +// // workaround for invalid signing time +// SigningTimeHelper.checkSigningTimeAgainstHostTime(si.sdi.getSignDate()); +// +// PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode); +// Signator signator = SignatorFactory.createSignator(algorithm); +// +// si.output = TempDirHelper.createTempDataSink(si.filename + "_signed.pdf"); +// +// signator.finishSign(si.si, si.output); + + si.outputAvailable = true; + } + + if (si.output.getMimeType().equals("text/xml") && si.outputAvailable) + { + // For "detached" signatures, the return value (data sink) is the response xml, + // but when passed through the BKU it is interpreted as another request + // which will generate a return code 1501 + // Then PDF-AS would answer with the response as well generating + // another 1501 and so forth. + // Therefor return it as TXT. + response.setContentType("text/plain"); + response.setCharacterEncoding("UTF-8"); + response.getWriter().println("Das detached XML kann nicht direkt durch die BKU geschliffen werden, weil diese es als Request interpretieren würde. Daher das XML als Text:"); + //response.getWriter().println(si.sdi.getSignSignatureObject().response_properties.getProperty(BKUPostConnection.RESPONSE_STRING_KEY)); + response.getWriter().println(new String(si.signedPdf, "UTF-8")); + } + else + { + // tzefferer: If PDF-AS has been called by an external web-application, we do not + // redirect to download.jsp but return the sign-response immediately + if (si.exappinf != null) { + log.debug("Entering external application interface mode. Skipping redirection to download page."); + SignServletHelper.returnSignResponse(si, request, response); + + // Not needed due to redirection of returnSignResponse. + // Just to clarify that there must not be any code after returnSignResponse. + return; + } else { + log.debug("Preparing download page."); + HttpSession session = request.getSession(true); + log.debug("Putting signed document into session (" + session.getId() + ")."); + session.setAttribute(SessionAttributes.SIGNED_PDF_DOCUMENT, si); + String downloadURL = response.encodeRedirectURL(LocalRequestHelper.getLocalContextAddress(request, response) + "/ProvidePDF"); + log.debug("Creating download URL \"" + downloadURL + "\"."); + session.setAttribute(SessionAttributes.DOWNLOAD_URL_FOR_SIGNED_PDF_DOCUMENT, downloadURL); + temporaryRedirect(response.encodeRedirectURL(LocalRequestHelper.getLocalContextAddress(request, response) + "/jsp/download.jsp") , response); + + // Not needed due to temporaryRedirect. + // Just to clarify that there must not be any code after temporaryRedirect. + return; + } + + // do not insert any code within this else block ! + } + } else { + log.debug("No XMLResponse found. Do nothing."); + } + } + + protected void processVerify(HttpServletRequest request, HttpServletResponse response, VerifySessionInformation si) throws ServletException, IOException, ConnectorException, SignatureException + { + log.trace("processVerify"); + + String xml_response = request.getParameter("XMLResponse"); //$NON-NLS-1$ + log.debug("xml_response = " + xml_response); //$NON-NLS-1$ + + if (isNullResponse(xml_response)) + { + log.debug("Received a NullOperationResponse -> answering with the first request."); //$NON-NLS-1$ + + assert si.currentLocalOperation.current_operation == 0; + } + else + { + log.debug("Recieved a normal response -> storing the response."); //$NON-NLS-1$ + +// Properties response_properties = new Properties(); +// response_properties.setProperty(BKUPostConnection.RESPONSE_STRING_KEY, xml_response); + + si.currentLocalOperation.finishCurrentOperation(xml_response); + } + + if (!si.currentLocalOperation.isFinished()) + { + log.debug("There are still requests to be performed -> answering with request #" + si.currentLocalOperation.current_operation); //$NON-NLS-1$ + + LocalRequest local_request = si.currentLocalOperation.getCurrentLocalRequest(); + + String request_string = local_request.getRequestString(); + + response.setContentType("text/xml"); + response.setCharacterEncoding("UTF-8"); + response.getWriter().println(request_string); + } + else + { + log.debug("All requests have been processed -> processing the responses."); //$NON-NLS-1$ + + + PdfAsInternal pdfAsInternal = ApiHelper.getPdfAsInternalFromContext(getServletContext()); + final ArrayList resList = new ArrayList(); + for (int i = 0; i < si.currentLocalOperation.response_xmls.length; i++) + { + SignatureInformation sigInfo = (SignatureInformation) si.currentLocalOperation.signaturesToBeverified.get(i); + +// PdfASID sig_kz = sh.getSignatureObject().getKZ(); +// String sig_id = sh.getSignatureObject().getSignationIds(); +// +// LocalConnector c = ConnectorChooser.chooseLocalConnectorForVerify(si.connector, sig_kz, sig_id, si.type, "loc ref content not needed here"); //$NON-NLS-1$ + + VerifyResult result = pdfAsInternal.finishLocalVerify(sigInfo, si.connector, si.type, "loc ref content not needed here", si.currentLocalOperation.response_xmls[i]); + resList.add(result); +// SignatureResponse sig_resp = c.analyzeVerifyResponse(si.currentLocalOperation.response_xmls[i]); +// results.add(sig_resp); + } + + si.currentLocalOperation = null; + + URL btlURL = new URL(LocalRequestHelper.getLocalContextAddress(request, response) + "/jsp/verifylist.jsp"); + String backToListURL = response.encodeURL(btlURL.toString()); + + VerifyResults results = new VerifyResults() { + + public List getResults() { + return resList; + } + }; + dispatchToResults(results, request, response, backToListURL); + } + + } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ProvidePDFServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ProvidePDFServlet.java new file mode 100644 index 0000000..fa3072d --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ProvidePDFServlet.java @@ -0,0 +1,119 @@ +package at.gv.egiz.pdfas.web.servlets; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import javax.servlet.RequestDispatcher; +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.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.web.FormFields; +import at.gv.egiz.pdfas.web.PDFContainer; +import at.gv.egiz.pdfas.web.helper.SignServletHelper; +import at.gv.egiz.pdfas.web.session.SessionAttributes; +import at.gv.egiz.pdfas.web.session.SignSessionInformation; +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; + +public class ProvidePDFServlet extends HttpServlet { + + /** + * SVUID. + */ + private static final long serialVersionUID = 1L; + + /** + * The log. + */ + private static Log log = LogFactory.getLog(ProvidePDFServlet.class); + + public static Set signedDocuments = Collections.synchronizedSet(new HashSet()); + + public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + String pdfIdString = request.getParameter(FormFields.FIELD_PDF_ID); + HttpSession session = request.getSession(); + + if (pdfIdString == null) { + log.debug("No " + FormFields.FIELD_PDF_ID + " provided. Trying to retrieve PDF from session (" + session.getId() + ")."); + SignSessionInformation si = (SignSessionInformation) session.getAttribute(SessionAttributes.SIGNED_PDF_DOCUMENT); + if (si == null) { + log.warn("Unable to find signed pdf in session (" + session.getId() + ")."); + SignServlet.prepareDispatchToErrorPage(new PresentableException(600, "Das signierte Dokument konnte nicht gefunden werden."), request); + response.setContentType("text/html"); + response.setCharacterEncoding("UTF-8"); + RequestDispatcher disp = super.getServletContext().getRequestDispatcher("/jsp/error.jsp"); + disp.forward(request, response); + return; + } else { + log.debug("Signed pdf found."); + // do NOT remove signed pdf document from session since IE9 loads this page/servlet twice...) + // Popup-Blocker, Link-Prefetching, IE 9 SmartScreen-Filter...??? + // session.removeAttribute(SessionAttributes.SIGNED_PDF_DOCUMENT); + log.debug("Returning signed pdf to browser."); + SignServletHelper.returnSignResponse(si, request, response); + log.debug("Removing free text (if any) from session."); + session.removeAttribute(UpdateFormServlet.UPLOADFORM_FREETEXT_KEY); + return; + } + } else { + long pdfId = Long.parseLong(pdfIdString); + + byte[] pdf = null; + + synchronized (signedDocuments) { + Iterator it = signedDocuments.iterator(); + + while (it.hasNext() && pdf == null) { + PDFContainer current = (PDFContainer) it.next(); + if (current.id == pdfId) { + pdf = current.pdf; + signedDocuments.remove(current); + } + } + } + + if (pdf != null) { + try { + + SignServletHelper.disableBrowserCacheForResponse(response); + response.setContentType("application/pdf"); + response.setContentLength(pdf.length); + + InputStream is = new ByteArrayInputStream(pdf); + final int bufferSize = 1024; + byte[] buffer = new byte[bufferSize]; + int len = -1; + while ((len = is.read(buffer)) != -1) { + response.getOutputStream().write(buffer, 0, len); + } + response.getOutputStream().flush(); + log.debug("File sent. Invalidating session."); + session.invalidate(); + } catch (IOException e) { + log.error("IO excepton while providing pdf document: " + e.getMessage(), e); + } + } else { + log.error("Unable to find signed pdf (id=" + pdfId + ") in session (" + session.getId() + ")."); + return; + } + + } + + } + + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + doPost(request, response); + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/RetrieveSignatureDataServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/RetrieveSignatureDataServlet.java new file mode 100644 index 0000000..c7fe841 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/RetrieveSignatureDataServlet.java @@ -0,0 +1,129 @@ +/** + * + */ +package at.gv.egiz.pdfas.web.servlets; + +import java.io.IOException; + +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 org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.api.commons.SignatureInformation; +import at.gv.egiz.pdfas.api.io.DataSource; +import at.gv.egiz.pdfas.api.verify.VerifyResult; +import at.gv.egiz.pdfas.exceptions.web.SessionExpiredException; +import at.gv.egiz.pdfas.web.helper.SessionHelper; +import at.gv.egiz.pdfas.web.session.SignSessionInformation; +import at.gv.egiz.pdfas.web.session.VerifySessionInformation; + +/** + * Retrieves the Signature Data from the session and returns it. + * + * @author wprinz + */ +public class RetrieveSignatureDataServlet extends HttpServlet +{ + + /** + * SVUID. + */ + private static final long serialVersionUID = -5387006236836240538L; + + /** + * The log. + */ + private static Log log = LogFactory.getLog(RetrieveSignatureDataServlet.class); + + 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); + } + +/** + * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + if (log.isDebugEnabled()) { + log.debug("Request for receiving signature data."); //$NON-NLS-1$ + log.debug("Requested session id is = " + request.getRequestedSessionId()); + } + + try + { + Object sessionObject = SessionHelper.getSession(request); + + if (sessionObject instanceof SignSessionInformation) + { + SignSessionInformation si = (SignSessionInformation) sessionObject; + processSign(request, response, si); + } + else + { + VerifySessionInformation si = (VerifySessionInformation) sessionObject; + processVerify(request, response, si); + } + } + catch (SessionExpiredException e) + { + log.error(e.getMessage(), e); + SignServlet.prepareDispatchToErrorPage(e, request); + dispatch(request, response, "/jsp/error.jsp"); + } + } + + protected void processSign(HttpServletRequest request, HttpServletResponse response, SignSessionInformation si) throws ServletException, IOException + { + writeSignatureData(si.sdi.getSignatureData(), response); + } + + protected void processVerify(HttpServletRequest request, HttpServletResponse response, VerifySessionInformation si) throws ServletException, IOException + { + + DataSource data = null; + if (si.currentLocalOperation != null) + { + data = ((SignatureInformation) si.currentLocalOperation.signaturesToBeverified.get(si.currentLocalOperation.current_operation)).getSignedData(); + } + else + { + data = ((VerifyResult)si.verifyResults.getResults().get(0)).getSignedData(); + } + + writeSignatureData(data, response); + } + + protected void writeSignatureData(DataSource ds, HttpServletResponse response) throws IOException + { + log.trace("Writing " + ds.getMimeType() + " data:"); //$NON-NLS-1$ //$NON-NLS-2$ + + response.setContentType(ds.getMimeType()); + response.setCharacterEncoding(ds.getCharacterEncoding()); + // [tknall] content length must be set, otherwise ITS BKU for Mac rejects the request. + response.setContentLength(ds.getLength()); + IOUtils.copy(ds.createInputStream(), response.getOutputStream()); + // response.getOutputStream().write(sd.getData()); + + log.trace("Writing SignatureData finished."); //$NON-NLS-1$ + } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignPreviewServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignPreviewServlet.java new file mode 100644 index 0000000..8d6a436 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignPreviewServlet.java @@ -0,0 +1,76 @@ +/** + * 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: SignPreview.java,v 1.2 2006/10/11 07:39:13 wprinz Exp $ + */ +package at.gv.egiz.pdfas.web.servlets; + +import java.io.IOException; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +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.web.helper.SessionHelper; +import at.gv.egiz.pdfas.web.helper.SignServletHelper; +import at.gv.egiz.pdfas.web.session.SignSessionInformation; + +/** + * @author wprinz + */ +public class SignPreviewServlet extends HttpServlet +{ + + protected static Log logger = LogFactory.getLog(SignPreviewServlet.class); + + /** + * SVUID. + */ + private static final long serialVersionUID = -8818532511322299998L; + + protected void dispatch(HttpServletRequest request, + HttpServletResponse response, String resource) throws ServletException, IOException + { + response.setContentType("text/html"); + response.setCharacterEncoding("UTF-8"); + + RequestDispatcher disp = getServletContext().getRequestDispatcher(resource); + disp.forward(request, response); + } + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + try + { + Object sessionObject = SessionHelper.getSession(request); + + SignSessionInformation si = (SignSessionInformation) sessionObject; + + SignServletHelper.finishSign(si, request, response, getServletContext()); + } + catch (PdfAsException e) { + logger.error(e.getMessage(), e); + + SignServlet.prepareDispatchToErrorPage(e, request); + dispatch(request, response, "/jsp/error.jsp"); + } + } +} 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 diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UpdateFormServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UpdateFormServlet.java new file mode 100644 index 0000000..24aa941 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UpdateFormServlet.java @@ -0,0 +1,56 @@ +package at.gv.egiz.pdfas.web.servlets; + +import java.io.IOException; + +import javax.servlet.RequestDispatcher; +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 at.gv.egiz.pdfas.web.FormFields; + +public class UpdateFormServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + public static final String UPLOADFORM_SIGNATURE_TYPE_KEY = "signupload.jsp:signatureType"; + public static final String UPLOADFORM_SIGNATURE_MODE_KEY = "signupload.jsp:signatureMode"; + public static final String UPLOADFORM_SIGNATURE_DEVICE_KEY = "signupload.jsp:signatureKey"; + public static final String UPLOADFORM_PDFA_KEY = "signupload.jsp:pdfaKey"; + public static final String UPLOADFORM_SOURCE_KEY = "signupload.jsp:sourceKey"; + public static final String UPLOADFORM_FREETEXT_KEY = "signupload.jsp:freeTextKey"; + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + this.doPost(request, response); + } + + public static void updateSession(HttpServletRequest request) { + String mode = request.getParameter(FormFields.FIELD_MODE); + String device = request.getParameter(FormFields.FIELD_CONNECTOR); + String type = request.getParameter(FormFields.FIELD_SIGNATURE_TYPE); + String pdfa = request.getParameter(FormFields.FIELD_PDFA_ENABLED); + String source = request.getParameter(FormFields.FIELD_SOURCE); + String freeText = request.getParameter(FormFields.FIELD_FREETEXT); + + HttpSession session = request.getSession(); + session.setAttribute(UPLOADFORM_SIGNATURE_DEVICE_KEY, device); + session.setAttribute(UPLOADFORM_SIGNATURE_MODE_KEY, mode); + session.setAttribute(UPLOADFORM_SIGNATURE_TYPE_KEY, type); + session.setAttribute(UPLOADFORM_PDFA_KEY, pdfa); + session.setAttribute(UPLOADFORM_SOURCE_KEY, source); + if (freeText != null) { + session.setAttribute(UPLOADFORM_FREETEXT_KEY, freeText); + } + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + updateSession(request); + + RequestDispatcher dispatcher = request.getRequestDispatcher("/jsp/signupload.jsp"); + dispatcher.forward(request, response); +// response.sendRedirect(response.encodeRedirectURL(request.getContextPath() + "/jsp/signupload.jsp")); + } + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyPreviewServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyPreviewServlet.java new file mode 100644 index 0000000..243e762 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyPreviewServlet.java @@ -0,0 +1,717 @@ +/** + * 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: VerifyPreview.java,v 1.4 2006/10/11 07:39:13 wprinz Exp $ + */ +package at.gv.egiz.pdfas.web.servlets; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +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 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.PdfAs; +import at.gv.egiz.pdfas.api.commons.Constants; +import at.gv.egiz.pdfas.api.commons.SignatureInformation; +import at.gv.egiz.pdfas.api.exceptions.PdfAsException; +import at.gv.egiz.pdfas.api.internal.PdfAsInternal; +import at.gv.egiz.pdfas.api.internal.SignatureEntry; +import at.gv.egiz.pdfas.api.verify.VerifyAfterAnalysisParameters; +import at.gv.egiz.pdfas.api.verify.VerifyResults; +import at.gv.egiz.pdfas.web.FormFields; +import at.gv.egiz.pdfas.web.helper.ApiHelper; +import at.gv.egiz.pdfas.web.helper.LocalRequestHelper; +import at.gv.egiz.pdfas.web.helper.SessionHelper; +import at.gv.egiz.pdfas.web.helper.WebSettingsReader; +import at.gv.egiz.pdfas.web.session.VerifySessionInformation; +import at.knowcenter.wag.egov.egiz.exceptions.SignatureException; + +/** + * @author wprinz + */ +public class VerifyPreviewServlet extends HttpServlet +{ + /** + * SVUID. + */ + private static final long serialVersionUID = 6954343542890239109L; + + public static String[] REQUIRED_SIG_KEYS = new String[] { "SIG_DATE", + "SIG_ISSUER", "SIG_VALUE", "SIG_NUMBER", "SIG_ID", "SIG_KZ" }; + + /** + * The logger. + */ + private static final Log logger_ = LogFactory.getLog(VerifyPreviewServlet.class); + + protected void dispatch(HttpServletRequest request, + HttpServletResponse response, String resource) throws ServletException, IOException + { + response.setContentType("text/html"); + response.setCharacterEncoding("UTF-8"); + + RequestDispatcher disp = getServletContext().getRequestDispatcher(resource); + disp.forward(request, response); + } + + protected void dispatchToPreview(HttpServletRequest request, HttpServletResponse response, String signedText, int verify_which)throws ServletException, IOException + { + request.setAttribute(FormFields.FIELD_VERIFY_WHICH, new Integer(verify_which)); + request.setAttribute(FormFields.FIELD_SIGNED_TEXT, signedText); + request.setAttribute("btlurl", formBackToListURL(request, response)); + dispatch(request, response, "/jsp/verifypreview.jsp"); + + } + + protected void dispatchToDataOk(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException + { + request.setAttribute("btlurl", formBackToListURL(request, response)); + dispatch(request, response, "/jsp/dataok.jsp"); + } + + protected String formBackToListURL(HttpServletRequest request, HttpServletResponse response) throws MalformedURLException + { + URL btlURL = new URL(LocalRequestHelper.getLocalContextAddress(request, response) + "/jsp/verifylist.jsp"); + String backToListURL = response.encodeURL(btlURL.toString()); + + return backToListURL; + } + + protected static String generateNamePrefix(int num) + { + return SIG_INPUT_PREFIX + num + "_"; + } + + // public static void formatPreview(List signature_holders, String connector, + // HttpServletRequest request, HttpServletResponse response) throws + // ServletException, IOException + // { + // response.setContentType("text/html"); + // response.setCharacterEncoding("UTF-8"); + // + // PrintWriter writer = response.getWriter(); + // + // writer.println(""); + // writer.println(""); + // writer.println(""); + // writer.println(""); + // writer.println("PDF-AS Amtssignaturen Vorschau"); + // writer.println(""); + // + // writer.println(""); + // + // writer.println(""); + // + // writer.println(""); + // writer.println("
"); + // + // writer.println("

PDF-AS Amtssignaturen

"); + // + // writer.println("
"); + // writer.println("
Vorschau: Dokument Prüfen
"); + // writer.println("
"); + // writer.println("
"); + // + // // writer.println(""); + // writer.println(""); + // + // // if (mode.equals(FormFields.VALUE_MODE_TEXTUAL)) + // // { + // // String raw_document_text = ((SignatureHolder) + // // signature_holders.get(0)).signed_text; + // // writer.println(""); + // // writer.println("
"); + // // } + // + // if (signature_holders.size() == 1) + // { + // writer.println("
Rekonstruktion der Signaturmarke:
"); + // } + // else + // { + // writer.println("
Rekonstruktion der Signaturmarken:
"); + // } + // + // // this special
is only needed because internet explorer doesn't + // // format the width of the + // // tables right when the div is not given. + // // probably this is because the table then tries to calculate the relative + // // width from the surrounding form object. + // writer.println("
"); + // int num = 0; + // Iterator it = signature_holders.iterator(); + // while (it.hasNext()) + // { + // SignatureHolder signature_holder = (SignatureHolder) it.next(); + // + // String name_prefix = generateNamePrefix(num); + // + // String input_key = name_prefix + FormFields.FIELD_RAW_DOCUMENT_TEXT; + // if (signature_holder.signature_object.isBinary()) + // { + // writer.println(""); + // } + // else + // { + // writer.println("
"); + // writer.println(""); + // writer.println("
"); + // } + // + // String html = renderRequiredKeys(signature_holder.signature_object, + // name_prefix, false); + // writer.println(html); + // + // writer.println(""); + // + // num++; + // } + // writer.println("
"); + // + // writer.println("");// + + // // FormFields.VALUE_VERIFY_WHICH_ALL + // // + + // // "\" + // // />"); + // writer.println(""); + // + // writer.println("
"); + // writer.println(""); + // writer.println("
"); + // + // writer.println("zurück"); + // + // writer.println("
"); + // writer.println(""); + // + // writer.println(""); + // + // } + + public static String renderRequiredKeysJavaScript(ServletContext sc, + SignatureInformation signatureInfo, String name_prefix) + { + StringWriter sw = new StringWriter(); + PrintWriter writer = new PrintWriter(sw); + + String[] rkeys = REQUIRED_SIG_KEYS; + + PdfAsInternal pdfAsInternal = ApiHelper.getPdfAsInternalFromContext(sc); + for (int key_idx = 0; key_idx < rkeys.length; key_idx++) + { + String key = rkeys[key_idx]; + SignatureEntry entry = pdfAsInternal.getSignatureEntryFromSignatureInformation(key, signatureInfo); + String value = entry.getValue(); + if ("SIG_ID".equals(key) && value == null) + { + continue; + } + if ("SIG_KZ".equals(key) && value == null) + { + continue; + } + + value = value.replaceAll("\\s", " "); + value = value.replaceAll("\\\"", "\\\""); + + String input_key = name_prefix + key; + + writer.println(" document.submitform." + input_key + ".value = \"" + value + "\";"); + } + + return sw.toString(); + } + + public static String renderRequiredKeys(ServletContext sc, SignatureInformation signatureInfo, + String name_prefix, boolean write_value) + { + StringWriter sw = new StringWriter(); + PrintWriter writer = new PrintWriter(sw); + + writer.println(""); + + String[] rkeys = REQUIRED_SIG_KEYS; + + PdfAsInternal pdfAsInternal = ApiHelper.getPdfAsInternalFromContext(sc); + for (int key_idx = 0; key_idx < rkeys.length; key_idx++) + { + String key = rkeys[key_idx]; + SignatureEntry entry = pdfAsInternal.getSignatureEntryFromSignatureInformation(key, signatureInfo); + String caption = entry.getCaption(); + String value = entry.getValue(); + if ("SIG_ID".equals(key) && value == null) + { + continue; + } + if ("SIG_KZ".equals(key) && value == null) + { + continue; + } + + writer.println(" "); + writer.println(" "); + writer.println(" "); + writer.println(" "); + } + writer.println("
" + caption + ":"); + + value = value.replaceAll("\\s", " "); + // wuhu! replacing all \" with \" + value = value.replaceAll("\\\"", "\\\""); + + String input_key = name_prefix + key; + writer.println(" "); + + writer.println("
"); + + return sw.toString(); + } + + public static String renderRequiredKeysText(ServletContext sc, SignatureInformation signatureInformation) + { + StringWriter sw = new StringWriter(); + PrintWriter writer = new PrintWriter(sw); + + writer.println(""); + + // just render useful information + // FIXME: NPE in case SignatureTypes.SIG_NAME is not used (in case of friendly signer name) + // Problem: SignatureTypes.SIG_NAME is defined as Signer-RFC2253Name, but there is not certain + // key for friendly name (e.g. SIG_SUBJECT or SIG_FOO), therefore we do not know which key contains + // the friendly signer name + + // workaround: include "SIG_SUBJECT" since it is usually used + String[] rkeys = { "SIG_NAME", "SIG_SUBJECT", "SIG_DATE", "SIG_ISSUER", "SIG_NUMBER"}; // SignatureTypes.REQUIRED_SIG_KEYS; + + PdfAsInternal pdfAsInternal = ApiHelper.getPdfAsInternalFromContext(sc); + for (int key_idx = 0; key_idx < rkeys.length; key_idx++) + { + String key = rkeys[key_idx]; + SignatureEntry entry = pdfAsInternal.getSignatureEntryFromSignatureInformation(key, signatureInformation); + if (entry == null) { + continue; + } + String caption = entry.getCaption(); + String value = entry.getValue(); + if (caption == null || value == null) { + continue; + } + +// if (SignatureTypes.SIG_KZ.equals(key) && value == null) +// { +// continue; +// } + + writer.println(" "); + writer.println(" "); + writer.println(" "); + writer.println(" "); + } + writer.println("
" + caption + ":"); + + value = value.replaceAll("\\s", " "); + value = value.replaceAll("\\\"", "\\\""); + + writer.println(" " + value); + + writer.println("
"); + + return sw.toString(); + } + + protected void dispatchToResults(VerifyResults verifyResults, HttpServletRequest request, + HttpServletResponse response, boolean backbutton, String backToListURL) throws ServletException, IOException + { + request.setAttribute("results", verifyResults); + request.setAttribute("backbutton", backbutton ? "true" : "false"); + request.setAttribute("btlurl", backToListURL); + dispatch(request, response, "/jsp/results.jsp"); + } + + // public static void formatVerifyResults(List results, + // HttpServletResponse response) throws IOException, SettingNotFoundException + // { + // response.setContentType("text/html"); + // response.setCharacterEncoding("UTF-8"); + // + // PrintWriter writer = response.getWriter(); + // + // writer.println(""); + // writer.println(""); + // writer.println(""); + // writer.println(""); + // writer.println("PDF-AS Amtssignaturen Resultat"); + // writer.println(""); + // writer.println(""); + // + // writer.println(""); + // writer.println("
"); + // + // writer.println("

PDF-AS Amtssignaturen

"); + // + // writer.println("
"); + // writer.println("
Resultat
"); + // writer.println("
"); + // + // Iterator it = results.iterator(); + // while (it.hasNext()) + // { + // SignatureResponse result = (SignatureResponse) it.next(); + // formatSignatureResponse(result, writer); + // + // if (it.hasNext()) + // { + // writer.println("
"); + // } + // } + // + // writer.println("
"); + // writer.println("
"); + // + // writer.println("zurück"); + // + // writer.println("
"); + // writer.println(""); + // + // writer.println(""); + // + // } + // + // public static void formatSignatureResponse(SignatureResponse result, + // PrintWriter writer) throws SettingNotFoundException + // { + // writer.println("
Zertifikat"); + // writer.println(""); + // writer.println(" "); + // writer.println(" "); + // writer.println(" "); + // List public_properties = result.getPublicProperties(); + // Iterator it = public_properties.iterator(); + // while (it.hasNext()) + // { + // String public_property = (String) it.next(); + // writer.println(" "); + // } + // + // writer.println(" "); + // + // writer.println("
Signator:" + + // result.getX509SubjectName() + "
Aussteller:" + + // result.getX509IssuerName() + "
Seriennummer:" + + // result.getX509SerialNumber() + "
Eigenschaft:" + + // public_property + "
Zertifikat:" + result.getCertificateCheckInfo() + // + "
"); + // writer.println("
"); + // writer.println("
Signatur-Check"); + // writer.println("
" + result.getSignatureCheckInfo() + "
"); + // writer.println("
"); + // writer.println("
Manifest-Check"); + // writer.println("
" + + // result.getSignatureManifestCheckInfo() + "
"); + // writer.println("
"); + // } + + /** + * Form field name prefix for signature table names + */ + public static final String SIG_INPUT_PREFIX = "sig_inp_"; + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + try + { + Object sessionObject = SessionHelper.getSession(request); + + VerifySessionInformation si = (VerifySessionInformation)sessionObject; + + + int verify_which = -1; + boolean preview = false; + + { + String str_verify_which = request.getParameter(FormFields.FIELD_VERIFY_WHICH); + logger_.debug("verify_which = " + str_verify_which); + if (str_verify_which.equals(FormFields.VALUE_VERIFY_WHICH_ALL)) + { + verify_which = -1; + } + else + { + verify_which = Integer.parseInt(str_verify_which); + } + logger_.debug("verify_which = " + verify_which); + } + + { + String preview_string = request.getParameter(FormFields.FIELD_PREVIEW); + if (preview_string.equals("true")) + { + preview = true; + } + } + + List holders_to_verify = si.analyzeResult.getSignatures(); + + if (verify_which >= 0) + { + if (verify_which >= si.analyzeResult.getSignatures().size()) + { + throw new SignatureException(312, "The selected signature to be verified doesn't exist."); + } + +// SignatureHolder holder = (SignatureHolder) si.signature_holders.get(verify_which); +// si.current_operation = verify_which; + + SignatureInformation sigInfo = (SignatureInformation) si.analyzeResult.getSignatures().get(verify_which); + holders_to_verify = new ArrayList(); + holders_to_verify.add(sigInfo); + + if (preview == true) + { + if (sigInfo.getSignatureType() == Constants.SIGNATURE_TYPE_BINARY) + { +// BinarySignatureHolder binary_holder = (BinarySignatureHolder) holder; + response.setContentType("application/pdf"); + IOUtils.copy(sigInfo.getSignedData().createInputStream(), response.getOutputStream()); +// StreamUtils.writeInputStreamToOutputStream(binary_holder.getSignedPdf().createInputStream(), response.getOutputStream()); +// response.getOutputStream().write(binary_holder.getSignedPdf(), 0, binary_holder.getSignedPdfLength()); + } + else + // if (holder.getSignatureObject().isTextual()) + { + // formatPreview(holders_to_verify, si.connector, request, + // response); +// request.setAttribute(FormFields.FIELD_VERIFY_WHICH, new Integer(verify_which)); + PdfAsInternal pdfAsInternal = ApiHelper.getPdfAsInternalFromContext(getServletContext()); + String signedText = pdfAsInternal.getSignedText(sigInfo); + dispatchToPreview(request, response, signedText, verify_which); + } + + return; + } + + } + + verifyAndDispatch(ApiHelper.getPdfAsInternalFromContext(getServletContext()), request, response, si, holders_to_verify, verify_which); + + } + catch (PdfAsException e) + { + logger_.error(e.getMessage(), e); + SignServlet.prepareDispatchToErrorPage(e, request); + dispatch(request, response, "/jsp/error.jsp"); + } + } + + private void verifyAndDispatch(PdfAsInternal pdfAsInternal, HttpServletRequest request, HttpServletResponse response, VerifySessionInformation si, List holders_to_verify, int verify_which) throws IOException, ServletException, PdfAsException { + if (LocalRequestHelper.isConnectorLocal(si.connector)) + { + String dispatch_to = LocalRequestHelper.processLocalVerify(pdfAsInternal, si, holders_to_verify, request, response); + dispatch(request, response, dispatch_to); + + return; + } + + PdfAs pdfAs = ApiHelper.getPdfAsFromContext(getServletContext()); + VerifyAfterAnalysisParameters verifyAfterAnalysisParameters = new VerifyAfterAnalysisParameters(); + verifyAfterAnalysisParameters.setAnalyzeResult(si.analyzeResult); + verifyAfterAnalysisParameters.setSignatureDevice(si.connector); + verifyAfterAnalysisParameters.setVerifySignatureIndex(verify_which); + VerifyResults verifyResults = pdfAs.verify(verifyAfterAnalysisParameters); + + boolean backbutton = true; + if (verify_which >= 0) + { + backbutton = false; + } + URL btlURL = new URL(LocalRequestHelper.getLocalContextAddress(request, response) + "/jsp/verifylist.jsp"); + String backToListURL = response.encodeURL(btlURL.toString()); + dispatchToResults(verifyResults, request, response, backbutton, backToListURL); + } + +protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + DiskFileItemFactory fif = new DiskFileItemFactory(); + fif.setRepository(WebSettingsReader.getTemporaryDirectory()); + ServletFileUpload sfu = new ServletFileUpload(fif); + + try + { + Object sessionObject = SessionHelper.getSession(request); + + PdfAsInternal pdfAsInternal = ApiHelper.getPdfAsInternalFromContext(getServletContext()); + + VerifySessionInformation si = (VerifySessionInformation)sessionObject; + + + String text_to_be_verified = null; + + int verify_which = -1; + boolean verify = false; + + List items = sfu.parseRequest(request); + + Map sigValues = new HashMap(); + Iterator it = items.iterator(); + while (it.hasNext()) + { + FileItem item = (FileItem) it.next(); + logger_.debug("item = " + item.getFieldName()); + + if (item.getFieldName().equals(FormFields.FIELD_RAW_DOCUMENT_TEXT)) + { + text_to_be_verified = item.getString("UTF-8"); +// String raw_document_text = item.getString("UTF-8"); +// text_to_be_verified = pdfAsInternal.normalizeText(raw_document_text); + continue; + } + + if (item.getFieldName().equals(FormFields.FIELD_VERIFY_WHICH)) + { + String which_str = item.getString("UTF-8"); + verify_which = Integer.parseInt(which_str); + continue; + } + + if (item.getFieldName().equals("verify")) + { + if (item.getString("UTF-8").equals("true")) + { + verify = true; + } + continue; + } + + String key = item.getFieldName(); + String value = item.getString("UTF-8"); + +// signature_object.setSigValue(key, value); + sigValues.put(key, value); + logger_.debug("sig_obj_number" + key + " = " + value); + } + +// SignatureHolder old_holder = (SignatureHolder) si.signature_holders.get(verify_which); +// TempDirHelper.deleteDataSourceIfFileBased(old_holder.getDataSource()); + +// TextDataSource tds = TempDirHelper.placeTextIntoTempDir(text_to_be_verified, "_previewholder.utf8.txt"); +// SignatureHolder new_holder = new TextualSignatureHolder(tds, signature_object); + +// si.signature_holders.set(verify_which, new_holder); + + si.analyzeResult = pdfAsInternal.analyzeFromRawText(text_to_be_verified, sigValues); + + if (verify == false) + { + dispatchToDataOk(request, response); + return; + } + + List holders_to_verify = si.analyzeResult.getSignatures(); + + if (verify_which >= 0) + { + if (verify_which >= si.analyzeResult.getSignatures().size()) + { + throw new SignatureException(312, "The selected signature to be verified doesn't exist."); + } + + SignatureInformation sigInfo = (SignatureInformation) si.analyzeResult.getSignatures().get(verify_which); + holders_to_verify = new ArrayList(); + holders_to_verify.add(sigInfo); + } + + verifyAndDispatch(pdfAsInternal, request, response, si, holders_to_verify, verify_which); + } + catch (FileUploadException e) + { + request.setAttribute("error", "verifypreviewservlet.error"); + request.setAttribute("cause", "verifypreviewservlet.cause"); + request.setAttribute("resourcebundle", Boolean.TRUE); + dispatch(request, response, "/jsp/error.jsp"); + } + catch (PdfAsException e) + { + logger_.error(e.getMessage(), e); + SignServlet.prepareDispatchToErrorPage(e, request); + dispatch(request, response, "/jsp/error.jsp"); + } + } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyServlet.java new file mode 100644 index 0000000..938f7bf --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyServlet.java @@ -0,0 +1,479 @@ +/* + * 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: Verify.java,v 1.7 2006/10/11 07:39:13 wprinz Exp $ + */ +package at.gv.egiz.pdfas.web.servlets; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +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.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.api.PdfAs; +import at.gv.egiz.pdfas.api.analyze.AnalyzeParameters; +import at.gv.egiz.pdfas.api.analyze.AnalyzeResult; +import at.gv.egiz.pdfas.api.commons.Constants; +import at.gv.egiz.pdfas.api.exceptions.PdfAsException; +import at.gv.egiz.pdfas.api.internal.PdfAsInternal; +import at.gv.egiz.pdfas.api.io.DataSource; +import at.gv.egiz.pdfas.api.verify.VerifyAfterAnalysisParameters; +import at.gv.egiz.pdfas.api.verify.VerifyResult; +import at.gv.egiz.pdfas.api.verify.VerifyResults; +import at.gv.egiz.pdfas.web.FormFields; +import at.gv.egiz.pdfas.web.helper.ApiHelper; +import at.gv.egiz.pdfas.web.helper.LocalRequestHelper; +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.io.TextDataSource; +import at.gv.egiz.pdfas.web.session.SessionAttributes; +import at.gv.egiz.pdfas.web.session.VerifySessionInformation; +import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; +import at.knowcenter.wag.egov.egiz.exceptions.SettingNotFoundException; + +/** + * This method is the verify 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 verify process. + * + * @author wlackner + * @author wprinz + */ +public class VerifyServlet extends HttpServlet +{ + + /** + * SVUID. + */ + private static final long serialVersionUID = 309198792358636766L; + + /** + * The log. + */ + private static Log log = LogFactory.getLog(SignServlet.class); + + protected void dispatch(HttpServletRequest request, HttpServletResponse response, String resource) throws ServletException, IOException + { + response.setContentType("text/html"); //$NON-NLS-1$ + response.setCharacterEncoding("UTF-8"); //$NON-NLS-1$ + + RequestDispatcher disp = getServletContext().getRequestDispatcher(resource); + disp.forward(request, response); + } + + protected void dispatchToResults(VerifyResults verifyResults, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + request.setAttribute("results", verifyResults); //$NON-NLS-1$ + dispatch(request, response, "/jsp/results.jsp"); //$NON-NLS-1$ + } + + /** + * Processes the verify 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 + { + // for performance measurement + long startTime = 0; + long fileSize = 0; + if (log.isInfoEnabled()) { + startTime = System.currentTimeMillis(); + } + try + { + UploadedData ud = retrieveUploadedDataFromRequest(request); + + VerifySessionInformation si = new VerifySessionInformation(); + si.connector = ud.sig_app; + si.application = "verify"; + si.mode = null; + si.inputDataSource = ud.dataSource; + si.type = null; +// si.user_name = null; +// si.user_password = null; + + PdfAs pdfAs = ApiHelper.getPdfAsFromContext(getServletContext()); + PdfAsInternal pdfAsInternal = ApiHelper.getPdfAsInternalFromContext(getServletContext()); + AnalyzeParameters analyzeParameters = new AnalyzeParameters(); + analyzeParameters.setDocument(ud.dataSource); + analyzeParameters.setVerifyMode(Constants.VERIFY_MODE_FULL_CONSERVATIVE); + AnalyzeResult analyzeResult = pdfAs.analyze(analyzeParameters); + si.analyzeResult = analyzeResult; + + // List signature_holders = extractSignatureHoldersFromFile(ud.file_name, + // ud.file_data); +// List signature_holders = extractSignatureHolders(ud.dataSource); +// +// TempDirHelper.storeTextSignatureHoldersIfApplicable(signature_holders, "_textholder.utf8.txt"); +// +// si.signature_holders = signature_holders; + + request.getSession().setAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION, si); + + if (ud.preview) + { + dispatch(request, response, "/jsp/verifylist.jsp"); + // VerifyPreview.formatPreview(signature_holders, connector, request, + // response); + } + else + { + if (LocalRequestHelper.isConnectorLocal(si.connector)) + { + String dispatch_to = LocalRequestHelper.processLocalVerify(pdfAsInternal, si, analyzeResult.getSignatures(), request, response); + + dispatch(request, response, dispatch_to); + return; + } + +// String host = request.getServerName(); + // TODO still required for old communication with MOA-SS/SP +// URL loc_ref_URL = new URL(WebUtils.addJSessionID(LocalRequestHelper.getLocalContextAddress(request, response) + "/RetrieveSignatureData", request)); +// URL loc_ref_URL = new URL(WebUtils.buildRetrieveSignatureDataURL(request, response)); +// String loc_ref_url = response.encodeURL(loc_ref_URL.toString()); + + VerifyAfterAnalysisParameters verifyAfterAnalysisParameters = new VerifyAfterAnalysisParameters(); + verifyAfterAnalysisParameters.setAnalyzeResult(si.analyzeResult); + verifyAfterAnalysisParameters.setSignatureDevice(si.connector); + verifyAfterAnalysisParameters.setVerifySignatureIndex(-1); + VerifyResults verifyResults = pdfAs.verify(verifyAfterAnalysisParameters); + si.verifyResults = verifyResults; + + dispatchToResults(verifyResults, request, response); + + // for performance measurement + if (log.isInfoEnabled()) { + long endTime = System.currentTimeMillis(); + String toReport = "VERIFY;"+ ud.file_name + ";"+ 0 + ";" + (endTime - startTime) + ";" + debugVerifyResults(verifyResults); + log.info(toReport); + } + + } + + } + catch (FileUploadException e) + { + request.setAttribute("error", "Fehler beim Upload der Daten"); + request.setAttribute("cause", "Beim Upload der Daten ist ein Fehler aufgetreten."); + dispatch(request, response, "/jsp/error_verify.jsp"); + } + catch (PdfAsException e) + { + log.error(e.getMessage(), e); + SignServlet.prepareDispatchToErrorPage(e, request); + dispatch(request, response, "/jsp/error_verify.jsp"); + } + + } + + 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 upload_fi = null; + FileItem connector_fi = null; + // FileItem mode_fi = null; + FileItem preview_fi = null; + + String characterEncoding = request.getCharacterEncoding(); + log.debug("request character encoding = " + characterEncoding); + + { + Iterator it = items.iterator(); + while (it.hasNext()) + { + FileItem item = (FileItem) it.next(); + log.debug("item = " + item.getFieldName()); //$NON-NLS-1$ + + 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_UPLOAD)) + { + upload_fi = item; + continue; + } + + if (item.getFieldName().equals(FormFields.FIELD_CONNECTOR)) + { + connector_fi = item; + continue; + } + + // if (item.getFieldName().equals(FormFields.FIELD_MODE)) + // { + // mode_fi = item; + // continue; + // } + + if (item.getFieldName().equals(FormFields.FIELD_PREVIEW)) + { + preview_fi = item; + continue; + } + + throw new ServletException("unrecognized POST data."); //$NON-NLS-1$ + } + } + + if (upload_fi == null || connector_fi == null || /* mode_fi == null || */preview_fi == null) + { + throw new ServletException("Unsufficient data provided in request."); //$NON-NLS-1$ + } + + String connector = connector_fi.getString("UTF-8"); //$NON-NLS-1$ + + // String mode = mode_fi.getString("UTF-8"); + // if (!mode.equals(FormFields.VALUE_MODE_BINARY) && + // !mode.equals(FormFields.VALUE_MODE_TEXTUAL)) + // { + // throw new ServletException("The mode '" + mode + "' is unrecognized."); + // } + + String preview_str = preview_fi.getString("UTF-8"); //$NON-NLS-1$ + if (!preview_str.equals(FormFields.VALUE_TRUE) && !preview_str.equals(FormFields.VALUE_FALSE)) + { + throw new ServletException("The preview '" + preview_str + "' is unrecognized."); //$NON-NLS-1$//$NON-NLS-2$ + } + boolean preview = false; + if (preview_str.equals(FormFields.VALUE_TRUE)) + { + preview = true; + } + + // process the request + DataSource dataSource = convertUploadToDataSource(upload_fi); + + UploadedData ud = new UploadedData(); + ud.preview = preview; + ud.sig_app = connector; + ud.file_name = upload_fi.getName(); + ud.dataSource = dataSource; + // ud.file_data = document_bytes; + + return ud; + } + + protected DataSource convertUploadToDataSource(FileItem upload_fi) throws PDFDocumentException + { + log.debug("file content type =" + upload_fi.getContentType()); //$NON-NLS-1$ + log.debug("file size = " + upload_fi.getSize()); //$NON-NLS-1$ + if (upload_fi.getSize() <= 0) + { + throw new PDFDocumentException(250, "The document is empty."); //$NON-NLS-1$ + } + + + // TR: do not check MIME-type of incoming file - might vary depending on the browser used + if ((upload_fi.getContentType() != null ) && ((upload_fi.getContentType().startsWith("application/pdf") || upload_fi.getContentType().startsWith("application/x-download") ))) + { + return new ByteArrayPdfDataSource(upload_fi.get()); +// try +// { +// String fileNameSuffix = TempDirHelper.extractFileNameSuffix(upload_fi.getName()); +// PdfDataSource pdfDataSource = TempDirHelper.placePdfIntoTempDir(upload_fi.getInputStream(), fileNameSuffix); +// return pdfDataSource; +// } +// catch (IOException e) +// { +// throw new PDFDocumentException(201, "The document could not be placed in the temp dir.", e); //$NON-NLS-1$ +// } + // byte[] document_bytes = upload_fi.get(); + } + + try + { +// String fileNameSuffix = TempDirHelper.extractFileNameSuffix(upload_fi.getName()); + String text = new String(upload_fi.get(), "UTF-8"); //$NON-NLS-1$ + TextDataSource textDataSource = new TextDataSource(text); + return textDataSource; + } + catch (IOException e) + { + throw new PDFDocumentException(201, e); + } + } +// +// protected List extractSignatureHolders(DataSource dataSource) throws PresentableException +// { +// VerificationFilterParameters parameters = SettingsHelper.readVerificationFilterParametersFromSettings(); +// +// ExtractionStage es = new ExtractionStage(); +// List signature_holders = es.extractSignatureHolders(dataSource, parameters); +// +// // filter out NoSignatureHolders that are possibly present due to the direct call method extractSignatureHolders() +// List filtered_signature_holders = new ArrayList(); +// Iterator it = signature_holders.iterator(); +// while(it.hasNext()) { +// SignatureHolder current = (SignatureHolder) it.next(); +// if(!(current instanceof NoSignatureHolder)) { +// filtered_signature_holders.add(current); +// } +// } +// +// if (filtered_signature_holders.size() == 0) +// { +// throw new PDFDocumentException(ErrorCode.DOCUMENT_NOT_SIGNED, "PDF document not signed."); //$NON-NLS-1$ +// } +// +// return filtered_signature_holders; +// } + + // TODO obsolete method - remove + // protected List extractSignatureHoldersFromFile(String file_name, byte[] + // data) throws UnsupportedEncodingException, PresentableException + // { + // VerificationFilterParameters parameters = new + // VerificationFilterParametersImpl(false, false, true); + // ExtractionStage es = new ExtractionStage(); + // // VerificationFilter vf = new VerificationFilter(); + // List signature_holders = null; + // + // String extension = extractExtension(file_name); + // + // String raw_text = null; + // if (file_name == null || (extension != null && extension.equals("txt"))) + // //$NON-NLS-1$ + // { + // raw_text = new String(data, "UTF-8"); //$NON-NLS-1$ + // + // signature_holders = es.extractSignatureHolders(new + // TextDataSourceImpl(raw_text), parameters); + // // signature_holders = vf.extractSignaturesFromPlainText(raw_text); + // } + // else + // { + // signature_holders = es.extractSignatureHolders(new + // ByteArrayPdfDataSourceImpl(data), parameters); + // + // // signature_holders = vf.extractSignaturesFromPdf(data); + // } + // + // if (signature_holders.size() == 0) + // { + // throw new PDFDocumentException(206, "PDF document not signed."); + // //$NON-NLS-1$ + // } + // + // return signature_holders; + // } + + /** + * Extracts the extension from a file name string. + * + *

+ * The extension of a file name is whatever text follows the last '.'. + *

+ * + * @param file_name + * The file name. + * @return Returns the extension. If the file name ends with the '.', then an + * empty string is returned. If the file name doesn't contain any '.' + * or file_name is null, null is returned. + */ + public static String extractExtension(String file_name) + { + if (file_name == null) + { + return null; + } + + int dot_index = file_name.lastIndexOf('.'); + if (dot_index < 0) + { + return null; + } + return file_name.substring(dot_index + 1); + } + + protected static class UploadedData + { + protected boolean preview = false; + + protected String sig_app = null; + + protected String file_name = null; + + protected DataSource dataSource = null; + // protected byte[] file_data = null; + } + + /** + * Formats the verification results for debugging. Returns 0 if no error occurs or the sum of all error-codes. + * + * @param verifyResults + * + * @param writer + * The output sink to write the formatted text to. + * @throws SettingNotFoundException + * Forwarded exception. + */ + protected static int debugVerifyResults(VerifyResults verifyResults) throws SettingNotFoundException + { + int toreturn = 0; + Iterator it = verifyResults.getResults().iterator(); + while (it.hasNext()) + { + VerifyResult result = (VerifyResult) it.next(); + + toreturn += result.getValueCheckCode().getCode(); + } + return toreturn; + } + + public boolean isPDF(byte[] data) { + final byte[] PDF_MAGIC_NUMBER = { (byte) 0x25, (byte) 0x50, (byte) + 0x44, (byte) 0x46 }; // %PDF + if (data == null || data.length < PDF_MAGIC_NUMBER.length) { + return false; + } + byte[] documentHeader = new byte[PDF_MAGIC_NUMBER.length]; + System.arraycopy(data, 0, documentHeader, 0, documentHeader.length); + return Arrays.equals(documentHeader, PDF_MAGIC_NUMBER); + } + + +} \ No newline at end of file diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/session/SessionAttributes.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/session/SessionAttributes.java new file mode 100644 index 0000000..3da6fa3 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/session/SessionAttributes.java @@ -0,0 +1,62 @@ +/** + * 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: SessionAttributes.java,v 1.2 2006/08/25 17:06:11 wprinz Exp $ + */ +package at.gv.egiz.pdfas.web.session; + +/** + * Helper class that provides constants for the session attributes. + * + * @author wprinz + */ +public abstract class SessionAttributes +{ + + /** + * The user name. + */ + public static final String ATTRIBUTE_USER_NAME = "uname"; + + /** + * The user password. + */ + public static final String ATTRIBUTE_USER_PASSWORD = "upass"; + + /** + * The attribute name under which the SessionInformation object is stored. + * + *

+ * The SessionInformation class contains type safe references to the objects. + *

+ */ + public static final String ATTRIBUTE_SESSION_INFORMATION = "session_information"; + + /** + * The signed pdf document. + */ + public static final String SIGNED_PDF_DOCUMENT = "at.gv.egiz.pdfas.web.SignSessionInformation:signedPDF"; + + /** + * The download URL for the signed pdf document. + */ + public static final String DOWNLOAD_URL_FOR_SIGNED_PDF_DOCUMENT = "java.lang.String:downloadURL"; + + /** + * The notification url of an external webapplication. + */ + public static final String PARENT_WEBAPP_REDIRECT_URL = "java.lang.String:parentWebAppRedirectURL"; + +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/session/SignSessionInformation.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/session/SignSessionInformation.java new file mode 100644 index 0000000..94428a4 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/session/SignSessionInformation.java @@ -0,0 +1,154 @@ +/** + * + */ +package at.gv.egiz.pdfas.web.session; + +import java.io.Serializable; + +import javax.servlet.http.HttpSessionBindingEvent; +import javax.servlet.http.HttpSessionBindingListener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.api.internal.LocalBKUParams; +import at.gv.egiz.pdfas.api.io.DataSink; +import at.gv.egiz.pdfas.api.io.DataSource; +import at.gv.egiz.pdfas.api.sign.SignParameters; +import at.gv.egiz.pdfas.api.sign.SignResult; +import at.gv.egiz.pdfas.api.sign.SignatureDetailInformation; +import at.gv.egiz.pdfas.api.sign.pos.SignaturePositioning; +import at.gv.egiz.pdfas.web.ExternAppInformation; +import at.gv.egiz.pdfas.web.LocalRequest; + +/** + * @author wprinz + * + */ +public class SignSessionInformation implements HttpSessionBindingListener, Serializable +{ + /** + * SVUID. + */ + private static final long serialVersionUID = 2739944460007369626L; + + /** + * The log. + */ + private static Log log = LogFactory.getLog(SignSessionInformation.class); + + /** + * The connector. + */ + public String connector = null; + + /** + * For local requests, tells the application (sign, verify). + */ + public String application = null; + + /** + * Tells the operation mode (binary, textual). + */ + public String mode = null; + + /** + * The original, uploaded pdf. + */ + public DataSource pdfDataSource = null; + + /** + * The type/profile of the signature. + */ + public String type = null; + + /** + * The suggested filename. + */ + public String filename; + + /** + * Tells, if the file download should be done inline or as attachment. + */ + public boolean download_inline; + + /** + * Object containing information about the calling webapplication. + * + * @author: Thomas Zefferer + */ + public ExternAppInformation exappinf; + + /** + * Information about the signature position + * + * @author exthex + */ + public SignaturePositioning pos; + + /** + * The SignatureDetailInformation. + */ + public SignatureDetailInformation sdi = null; + + /** + * The DataSink to write the output data to. + */ + public DataSink output = null; + + /** + * The local request to be sent to the device. + */ + public LocalRequest localRequest = null; + +// /** +// * The response properties of the local request. +// */ +// public Properties response_properties = null; + + /** + * Tells if the sign request has been processed and the signed document is + * available in the DataSink. + */ + public boolean outputAvailable = false; + + /** + * The SignParameters + */ + public SignParameters signParameters; + + public SignResult signResult; + + public byte[] signedPdf; + + public String xmlResponse; + + public LocalBKUParams localBKUParams; + + + /** + * @see javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.http.HttpSessionBindingEvent) + */ + public void valueBound(HttpSessionBindingEvent event) + { + log.debug("Bound SignSessionInformation to session (ID=" + event.getSession().getId() + ")."); + } + + /** + * @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(javax.servlet.http.HttpSessionBindingEvent) + */ + public void valueUnbound(HttpSessionBindingEvent event) + { + log.debug("Unbound SignSessionInformation from session (ID=" + event.getSession().getId() + ")."); + + //TODO needed? +// if (this.pdfDataSource != null) +// { +// TempDirHelper.deleteDataSourceIfFileBased(this.pdfDataSource); +// } +// if (this.output != null) +// { +// TempDirHelper.deleteDataSinkIfFileBased(this.output); +// } + } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/session/VerifySessionInformation.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/session/VerifySessionInformation.java new file mode 100644 index 0000000..bbaa647 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/session/VerifySessionInformation.java @@ -0,0 +1,198 @@ +/** + * 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: SessionInformation.java,v 1.2 2006/08/25 17:06:11 wprinz Exp $ + */ +package at.gv.egiz.pdfas.web.session; + +import java.io.Serializable; + +import javax.servlet.http.HttpSessionBindingEvent; +import javax.servlet.http.HttpSessionBindingListener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.api.analyze.AnalyzeResult; +import at.gv.egiz.pdfas.api.io.DataSource; +import at.gv.egiz.pdfas.api.verify.VerifyResults; +import at.gv.egiz.pdfas.web.CurrentLocalOperation; +import at.gv.egiz.pdfas.web.ExternAppInformation; + +/** + * This class is a collection of various session parameters that are passed + * between the servlets and jsps. + * + *

+ * The SessionInformation class contains type safe references to the objects. + *

+ * + * @author wprinz + */ +public class VerifySessionInformation implements HttpSessionBindingListener, Serializable +{ + + /** + * SVUID. + */ + private static final long serialVersionUID = -7413884936584659150L; + + /** + * The log. + */ + private static Log log = LogFactory.getLog(VerifySessionInformation.class); + + /** + * The connector. + */ + public String connector = null; + + /** + * For local requests, tells the application (sign, verify). + */ + public String application = null; + + /** + * Tells the operation mode (binary, textual). + */ + public String mode = null; + + /** + * The original, uploaded pdf. + */ + //public FileBasedPdfDataSourceImpl pdfDataSource = null; + public DataSource inputDataSource = null; + + /** + * The type/profile of the signature. + */ + public String type = null; + +// /** +// * The user name. +// */ +// public String user_name = null; +// +// /** +// * The password. +// */ +// public String user_password = null; + +// /** +// * All SignatureHolders extracted from the document. +// */ +// public List signature_holders; + + /** + * Keeps track of the currently running local operation. + * + *

+ * Only valid during local verify. + *

+ */ + public CurrentLocalOperation currentLocalOperation = null; + +// /** +// * This is used only for MOA loc-ref web verify. +// */ +// public SignatureHolder moa_holder; + + +// /** +// * The incremental update information that has been extracted from the given +// * PDF document. +// */ +// public IncrementalUpdateInformation iui; + +// public SignatorInformation si = null; + +// public FileBasedDataSink output = null; + + +// /** +// * Copy of signature holders. It's needed by BKU when we try to verify single by single +// * signature. +// */ +// public List copy_of_signature_holders; + +// /** +// * The suggested filename. +// */ +// public String filename; +// +// /** +// * Tells, if the file download should be done inline or as attachment. +// */ +// public boolean download_inline; + +//// /** +//// * The sign result to be passed back to the user. +//// */ +//// public SignResult sign_result; +// +// public boolean isSignFinished = false; + + + + /** + * Object containing information about the calling webapplication. + * @author: Thomas Zefferer + */ + public ExternAppInformation exappinf; + + public AnalyzeResult analyzeResult; + + public VerifyResults verifyResults; + +// /** +// * Information about the signature position +// * @author: Thomas Zefferer +// */ +// public TablePos pos ; + + + + /** + * @see javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.http.HttpSessionBindingEvent) + */ + public void valueBound(HttpSessionBindingEvent event) + { + log.debug("Bound SignSessionInformation to session."); + } + + /** + * @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(javax.servlet.http.HttpSessionBindingEvent) + */ + public void valueUnbound(HttpSessionBindingEvent event) + { + log.debug("Unbound SignSessionInformation from session."); + + //TODO needed? +// if (this.inputDataSource != null) +// { +// TempDirHelper.deleteDataSourceIfFileBased(this.inputDataSource); +// } +// if (this.signature_holders != null) +// { +// Iterator it = this.signature_holders.iterator(); +// while (it.hasNext()) +// { +// SignatureHolder sh = (SignatureHolder) it.next(); +// TempDirHelper.deleteDataSourceIfFileBased(sh.getDataSource()); +// } +// } + } + +} -- cgit v1.2.3