aboutsummaryrefslogtreecommitdiff
path: root/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper
diff options
context:
space:
mode:
Diffstat (limited to 'pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper')
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/ApiHelper.java73
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/LocalRequestHelper.java331
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SessionHelper.java47
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java342
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SigningTimeHelper.java71
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/WebSettingsReader.java210
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/WebUtils.java92
7 files changed, 1166 insertions, 0 deletions
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> Copyright (c) 2006 by Know-Center, Graz, Austria </copyright>
+ *
+ * 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.
+ *
+ * <p>
+ * As stated in the BKU tutorial, this response must be plain text "<ok/>".
+ * Otherwise BKU will assume a failure.
+ * </p>
+ *
+ * @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("<ok/>");
+ }
+
+ /**
+ * Prepares the dispatch to the local data connection page.
+ *
+ * <p>
+ * The calling servlet just has to dispatch to the jsp after calling this
+ * method.
+ * </p>
+ *
+ * @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("&", "&amp;");
+ output = output.replaceAll("\"", "&quot;");
+ output = output.replaceAll("<", "&lt;");
+ output = output.replaceAll(">", "&gt;");
+ 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.
+ *
+ * <p>
+ * This prepares the data for both being signed or being previewed.
+ * </p>
+ *
+ * @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.
+ *
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @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;
+ }
+
+}