From 030ad8ea8455922ad59c095d3a9ecbfc462ff69f Mon Sep 17 00:00:00 2001 From: Andreas Fitzek Date: Tue, 14 Jul 2015 13:27:56 +0200 Subject: many fixes for html5 js viewer integration --- .../pdfas/web/filter/ExceptionCatchFilter.java | 4 +- .../gv/egiz/pdfas/web/filter/UserAgentFilter.java | 2 +- .../at/gv/egiz/pdfas/web/helper/PdfAsHelper.java | 194 ++++++++++++++++++-- .../pdfas/web/helper/PdfAsParameterExtractor.java | 29 ++- .../egiz/pdfas/web/servlets/ExternSignServlet.java | 62 ++++++- .../web/servlets/PDFPositioningDataServlet.java | 70 +++++++ .../gv/egiz/pdfas/web/servlets/SignNowServlet.java | 202 +++++++++++++++++++++ pdf-as-web/src/main/webapp/WEB-INF/web.xml | 20 ++ pdf-as-web/src/main/webapp/assets/js/dragNdrop.js | 8 +- .../src/main/webapp/assets/js/pdf.js/web/app.js | 70 +++++-- .../assets/js/pdf.js/web/images/signature-icon.png | Bin 0 -> 417 bytes .../js/pdf.js/web/images/signature-icon@2x.png | Bin 0 -> 417 bytes .../main/webapp/assets/js/pdf.js/web/viewer.css | 5 + .../main/webapp/assets/js/pdf.js/web/viewer.html | 7 +- pdf-as-web/src/main/webapp/index.jsp | 2 +- 15 files changed, 632 insertions(+), 43 deletions(-) create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFPositioningDataServlet.java create mode 100644 pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignNowServlet.java create mode 100644 pdf-as-web/src/main/webapp/assets/js/pdf.js/web/images/signature-icon.png create mode 100644 pdf-as-web/src/main/webapp/assets/js/pdf.js/web/images/signature-icon@2x.png (limited to 'pdf-as-web/src/main') diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/ExceptionCatchFilter.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/ExceptionCatchFilter.java index 4713e84f..b81b8366 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/ExceptionCatchFilter.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/ExceptionCatchFilter.java @@ -66,7 +66,7 @@ public class ExceptionCatchFilter implements Filter { //try { if(request instanceof HttpServletRequest) { - logger.debug("Processing Parameters into Attributes"); + logger.trace("Processing Parameters into Attributes"); HttpServletRequest httpRequest = (HttpServletRequest)request; PdfAsHelper.logAccess(httpRequest); @SuppressWarnings("unchecked") @@ -75,7 +75,7 @@ public class ExceptionCatchFilter implements Filter { String name = parameterNames.nextElement(); String value = httpRequest.getParameter(name); request.setAttribute(name, value); - logger.debug("Setting attribute: " + name + " - " + value); + logger.trace("Setting attribute: " + name + " - " + value); } } diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/UserAgentFilter.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/UserAgentFilter.java index 504cf472..b1692ad0 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/UserAgentFilter.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/UserAgentFilter.java @@ -37,7 +37,7 @@ public class UserAgentFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if(request instanceof HttpServletRequest) { - logger.debug("Processing Parameters into Attributes"); + logger.trace("Processing Parameters into Attributes"); HttpServletRequest httpRequest = (HttpServletRequest)request; requestUserAgent.set(httpRequest.getHeader("User-Agent")); } diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java index 52eb8468..ab23e238 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java @@ -36,6 +36,7 @@ import java.security.cert.CertificateException; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.UUID; import javax.imageio.ImageIO; import javax.servlet.RequestDispatcher; @@ -76,6 +77,7 @@ import at.gv.egiz.pdfas.sigs.pades.PAdESSigner; import at.gv.egiz.pdfas.sigs.pades.PAdESSignerKeystore; import at.gv.egiz.pdfas.web.config.WebConfiguration; import at.gv.egiz.pdfas.web.exception.PdfAsWebException; +import at.gv.egiz.pdfas.web.servlets.PDFPositioningDataServlet; import at.gv.egiz.pdfas.web.servlets.UIEntryPointServlet; import at.gv.egiz.pdfas.web.stats.StatisticEvent; import at.gv.egiz.sl.schema.CreateCMSSignatureResponseType; @@ -117,6 +119,16 @@ public class PdfAsHelper { private static final String SIGNATURE_ACTIVE = "SIGNATURE_ACTIVE"; private static final String VERIFICATION_RESULT = "VERIFICATION_RESULT"; private static final String QRCODE_CONTENT = "QR_CONT"; + private static final String PDF_DATA = "PDF_DATA"; + private static final String PDF_DATA_TOKEN = "PDF_DATA_TOKEN"; + private static final String PDF_CONNECTOR = "CONNECTOR"; + private static final String PDF_TRANSACTION = "TID"; + private static final String SIG_TYPE = "SIG_TYPE"; + private static final String PRE_PROCESSOR_MAP = "PREPROCMAP"; + private static final String OVERWRITE_MAP = "OVERWRITEMAP"; + private static final String KEYID = "KEYID"; + + private static final String POSITIONING_URL = "/assets/js/pdf.js/web/viewer.html"; private static final Logger logger = LoggerFactory .getLogger(PdfAsHelper.class); @@ -286,9 +298,54 @@ public class PdfAsHelper { sb.append("f:0;"); } + logger.debug("Build position string: {}", sb.toString()); + return sb.toString(); } + public static String storePdfData(byte[] data, HttpServletRequest request) + throws UnsupportedEncodingException { + String token = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8"); + HttpSession session = request.getSession(); + session.setAttribute(PDF_DATA, data); + session.setAttribute(PDF_DATA_TOKEN, token); + logger.info("Stored pdf data and token {} into session {}", token, session.getId()); + return token; + } + + public static byte[] getPdfData(String token, HttpServletRequest request) + throws UnsupportedEncodingException { + HttpSession session = request.getSession(); + logger.info("Fetching pdf data and token {} from session {}", token, session.getId()); + String storedToken = (String) session.getAttribute(PDF_DATA_TOKEN); + byte[] data = null; + if (storedToken != null) { + if (storedToken.equals(token)) { + data = (byte[]) session.getAttribute(PDF_DATA); + } else { + logger.warn("PDF Data token missmatch!"); + } + } else { + logger.warn("No PDF Data token stored!"); + } + return data; + } + + public static byte[] getPdfData(HttpServletRequest request) + throws UnsupportedEncodingException { + HttpSession session = request.getSession(); + logger.info("Fetching pdf data from session {}", session.getId()); + byte[] data = (byte[]) session.getAttribute(PDF_DATA); + return data; + } + + public static void clearPdfData(HttpServletRequest request) + throws UnsupportedEncodingException { + HttpSession session = request.getSession(); + logger.info("Removing pdf data from session {}", session.getId()); + session.removeAttribute(PDF_DATA); + } + public static List synchornousVerify( HttpServletRequest request, HttpServletResponse response, byte[] pdfData) throws Exception { @@ -361,10 +418,10 @@ public class PdfAsHelper { Configuration config = pdfAs.getConfiguration(); - - Map configOverwrite = PdfAsParameterExtractor.getOverwriteMap(request); + Map configOverwrite = PdfAsHelper + .getOverwriteMap(request); ConfigurationOverwrite.overwriteConfiguration(configOverwrite, config); - + ByteArrayOutputStream baos = new ByteArrayOutputStream(); // Generate Sign Parameter @@ -372,7 +429,7 @@ public class PdfAsHelper { new ByteArrayDataSource(pdfData), baos); // Get Connector - String connector = PdfAsParameterExtractor.getConnector(request); + String connector = PdfAsHelper.getConnector(request); if (!connector.equals("moa") && !connector.equals("jks")) { throw new PdfAsWebException("Invalid connector (moa | jks)"); @@ -381,7 +438,7 @@ public class PdfAsHelper { IPlainSigner signer; if (connector.equals("moa")) { - String keyIdentifier = PdfAsParameterExtractor + String keyIdentifier = PdfAsHelper .getKeyIdentifier(request); if (keyIdentifier != null) { @@ -408,7 +465,7 @@ public class PdfAsHelper { signer = new PAdESSigner(new MOAConnector(config)); } else if (connector.equals("jks")) { - String keyIdentifier = PdfAsParameterExtractor + String keyIdentifier = PdfAsHelper .getKeyIdentifier(request); boolean ksEnabled = false; @@ -463,7 +520,7 @@ public class PdfAsHelper { signParameter.setPlainSigner(signer); - String profileId = PdfAsParameterExtractor.getSigType(request); + String profileId = PdfAsHelper.getSignatureType(request); String qrCodeContent = PdfAsHelper.getQRCodeContent(request); if (qrCodeContent != null) { @@ -516,8 +573,10 @@ public class PdfAsHelper { PDFASSignParameters params) throws Exception { Configuration config = pdfAs.getConfiguration(); - if (WebConfiguration.isAllowExtOverwrite() && params.getOverrides() != null) { - ConfigurationOverwrite.overwriteConfiguration(params.getOverrides().getMap(), config); + if (WebConfiguration.isAllowExtOverwrite() + && params.getOverrides() != null) { + ConfigurationOverwrite.overwriteConfiguration(params.getOverrides() + .getMap(), config); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); @@ -668,7 +727,8 @@ public class PdfAsHelper { HttpServletResponse response, ServletContext context, byte[] pdfData, String connector, String position, String transactionId, String profile, - Map preProcessor, Map overwrite) throws Exception { + Map preProcessor, Map overwrite) + throws Exception { // TODO: Protect session so that only one PDF can be signed during one // session @@ -689,7 +749,7 @@ public class PdfAsHelper { session.setAttribute(PDF_CONFIG, config); ConfigurationOverwrite.overwriteConfiguration(overwrite, config); - + ByteArrayOutputStream baos = new ByteArrayOutputStream(); session.setAttribute(PDF_OUTPUT, baos); @@ -840,7 +900,7 @@ public class PdfAsHelper { public static void logAccess(HttpServletRequest request) { HttpSession session = request.getSession(); - logger.debug("Access to " + request.getServletPath() + " in Session: " + logger.trace("Access to " + request.getServletPath() + " in Session: " + session.getId()); } @@ -1193,6 +1253,29 @@ public class PdfAsHelper { return generateURL(request, response, PDF_PDFDATA_PAGE); } + public static String generatePositioningURL(String token, + HttpServletRequest request, HttpServletResponse response) { + String publicURL = WebConfiguration.getPublicURL(); + if (publicURL == null) { + logger.error("To use this functionality " + + WebConfiguration.PUBLIC_URL + + " has to be configured in the web configuration"); + return null; + } + + String pdfDataUrl = generateURL(request, response, "/PDFPosData") + "?" + + PDFPositioningDataServlet.PARAM_TOKEN + "=" + token; + + try { + String positioningUrl = generateURL(request, response, POSITIONING_URL) + "?file" + "=" + + URLEncoder.encode(pdfDataUrl, "UTF-8") + "&running=true"; + return positioningUrl; + } catch (UnsupportedEncodingException e) { + logger.error("Failed to generate positioning URL!", e); + return null; + } + } + public static String generateUserEntryURL(String storeId) { String publicURL = WebConfiguration.getPublicURL(); if (publicURL == null) { @@ -1252,6 +1335,51 @@ public class PdfAsHelper { } return ""; } + + public static void setSignatureType(HttpServletRequest request, + String value) { + HttpSession session = request.getSession(); + session.setAttribute(SIG_TYPE, value); + } + + public static String getSignatureType(HttpServletRequest request) { + HttpSession session = request.getSession(); + Object obj = session.getAttribute(SIG_TYPE); + if (obj != null) { + return obj.toString(); + } + return null; + } + + public static void setPreProcessorMap(HttpServletRequest request, + Map value) { + HttpSession session = request.getSession(); + session.setAttribute(PRE_PROCESSOR_MAP, value); + } + + public static Map getPreProcessorMap(HttpServletRequest request) { + HttpSession session = request.getSession(); + Object obj = session.getAttribute(PRE_PROCESSOR_MAP); + if (obj != null) { + return (Map)obj; + } + return null; + } + + public static void setOverwriteMap(HttpServletRequest request, + Map value) { + HttpSession session = request.getSession(); + session.setAttribute(OVERWRITE_MAP, value); + } + + public static Map getOverwriteMap(HttpServletRequest request) { + HttpSession session = request.getSession(); + Object obj = session.getAttribute(OVERWRITE_MAP); + if (obj != null) { + return (Map)obj; + } + return null; + } public static void setQRCodeContent(HttpServletRequest request, String value) { HttpSession session = request.getSession(); @@ -1267,6 +1395,48 @@ public class PdfAsHelper { return null; } + public static void setConnector(HttpServletRequest request, String value) { + HttpSession session = request.getSession(); + session.setAttribute(PDF_CONNECTOR, value); + } + + public static String getConnector(HttpServletRequest request) { + HttpSession session = request.getSession(); + Object obj = session.getAttribute(PDF_CONNECTOR); + if (obj != null) { + return obj.toString(); + } + return null; + } + + public static void setKeyIdentifier(HttpServletRequest request, String value) { + HttpSession session = request.getSession(); + session.setAttribute(KEYID, value); + } + + public static String getKeyIdentifier(HttpServletRequest request) { + HttpSession session = request.getSession(); + Object obj = session.getAttribute(KEYID); + if (obj != null) { + return obj.toString(); + } + return null; + } + + public static void setTransactionid(HttpServletRequest request, String value) { + HttpSession session = request.getSession(); + session.setAttribute(PDF_TRANSACTION, value); + } + + public static String getTransactionid(HttpServletRequest request) { + HttpSession session = request.getSession(); + Object obj = session.getAttribute(PDF_TRANSACTION); + if (obj != null) { + return obj.toString(); + } + return null; + } + public static void setPDFFileName(HttpServletRequest request, String value) { HttpSession session = request.getSession(); session.setAttribute(PDF_FILE_NAME, value); diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsParameterExtractor.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsParameterExtractor.java index 1c515efa..53335ba6 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsParameterExtractor.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsParameterExtractor.java @@ -62,6 +62,9 @@ public class PdfAsParameterExtractor { public static final String PARAM_SIG_POS_P = "sig-pos-p"; public static final String PARAM_SIG_POS_Y = "sig-pos-y"; public static final String PARAM_SIG_POS_X = "sig-pos-x"; + public static final String PARAM_SIG_POS_P_ALT = "sigPosP"; + public static final String PARAM_SIG_POS_Y_ALT = "sigPosY"; + public static final String PARAM_SIG_POS_X_ALT = "sigPosX"; public static final String PARAM_SIG_POS_W = "sig-pos-w"; public static final String PARAM_SIG_POS_R = "sig-pos-r"; public static final String PARAM_SIG_POS_F = "sig-pos-f"; @@ -71,7 +74,15 @@ public class PdfAsParameterExtractor { public static final String PARAM_PREPROCESSOR_PREFIX = "pp:"; public static final String PARAM_OVERWRITE_PREFIX = "ov:"; public static final String PARAM_QRCODE_CONTENT = "qrcontent"; + public static final String PARAM_USER_POSITIONING = "upos"; + public static boolean isUserPositioning(HttpServletRequest request) { + String paramerterValue = (String)request.getAttribute(PARAM_USER_POSITIONING); + if(paramerterValue != null) { + return Boolean.parseBoolean(paramerterValue); + } + return false; + } public static String getConnector(HttpServletRequest request) { String connector = (String)request.getAttribute(PARAM_CONNECTOR); @@ -201,15 +212,27 @@ public class PdfAsParameterExtractor { } public static String getSigPosP(HttpServletRequest request) { - return (String)request.getAttribute(PARAM_SIG_POS_P); + if(request.getAttribute(PARAM_SIG_POS_P) != null) { + return (String)request.getAttribute(PARAM_SIG_POS_P); + } else { + return (String)request.getAttribute(PARAM_SIG_POS_P_ALT); + } } public static String getSigPosY(HttpServletRequest request) { - return (String)request.getAttribute(PARAM_SIG_POS_Y); + if(request.getAttribute(PARAM_SIG_POS_Y) != null) { + return (String)request.getAttribute(PARAM_SIG_POS_Y); + } else { + return (String)request.getAttribute(PARAM_SIG_POS_Y_ALT); + } } public static String getSigPosX(HttpServletRequest request) { - return (String)request.getAttribute(PARAM_SIG_POS_X); + if(request.getAttribute(PARAM_SIG_POS_X) != null) { + return (String)request.getAttribute(PARAM_SIG_POS_X); + } else { + return (String)request.getAttribute(PARAM_SIG_POS_X_ALT); + } } public static String getSigPosW(HttpServletRequest request) { diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java index 9e217058..a06177e3 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java @@ -26,6 +26,7 @@ package at.gv.egiz.pdfas.web.servlets; import java.io.File; import java.io.IOException; import java.util.List; +import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -289,8 +290,10 @@ public class ExternSignServlet extends HttpServlet { HttpServletResponse response, byte[] pdfData, StatisticEvent statisticEvent) throws Exception { // Get Connector String connector = PdfAsParameterExtractor.getConnector(request); + PdfAsHelper.setConnector(request, connector); String transactionId = PdfAsParameterExtractor.getTransactionId(request); + PdfAsHelper.setTransactionid(request, transactionId); statisticEvent.setFilesize(pdfData.length); statisticEvent.setProfileId(null); @@ -329,8 +332,25 @@ public class ExternSignServlet extends HttpServlet { PdfAsHelper.setSignatureDataHash(request, pdfDataHash); logger.debug("Storing signatures data hash: " + pdfDataHash); + boolean manualPositioning = PdfAsParameterExtractor.isUserPositioning(request); + logger.debug("Starting signature creation with: " + connector); + String sigType = PdfAsParameterExtractor + .getSigType(request); + PdfAsHelper.setSignatureType(request, sigType); + + Map preProcessorMap = PdfAsParameterExtractor.getPreProcessorMap(request); + PdfAsHelper.setPreProcessorMap(request, preProcessorMap); + + Map overwriteMap = PdfAsParameterExtractor.getOverwriteMap(request); + PdfAsHelper.setOverwriteMap(request, overwriteMap); + + String keyIdentifier = PdfAsParameterExtractor.getKeyIdentifier(request); + PdfAsHelper.setKeyIdentifier(request, keyIdentifier); + + PdfAsHelper.setStatisticEvent(request, response, statisticEvent); + //IPlainSigner signer; if (connector.equals("bku") || connector.equals("onlinebku") || connector.equals("mobilebku")) { // start asynchronous signature creation @@ -351,21 +371,33 @@ public class ExternSignServlet extends HttpServlet { if(WebConfiguration.getLocalBKUURL() == null) { throw new PdfAsWebException("Invalid connector mobilebku is not supported"); } - } + } - PdfAsHelper.setStatisticEvent(request, response, statisticEvent); + if(manualPositioning) { + // store pdf data + // redirect to viewer html + String token = PdfAsHelper.storePdfData(pdfData, request); + + String pdfDataUrl = PdfAsHelper.generatePositioningURL(token, request, response); + + if(pdfDataUrl != null) { + response.sendRedirect(response.encodeRedirectURL(pdfDataUrl)); + return; + } else { + // remove Pdf data form session again! + PdfAsHelper.getPdfData(token, request); + } + } PdfAsHelper.startSignature(request, response, getServletContext(), pdfData, connector, - PdfAsHelper.buildPosString(request, response), transactionId, PdfAsParameterExtractor - .getSigType(request), PdfAsParameterExtractor.getPreProcessorMap(request), - PdfAsParameterExtractor.getOverwriteMap(request)); + PdfAsHelper.buildPosString(request, response), transactionId, sigType, + preProcessorMap, + overwriteMap); return; } else if (connector.equals("jks") || connector.equals("moa")) { // start synchronous siganture creation if(connector.equals("jks")) { - - String keyIdentifier = PdfAsParameterExtractor.getKeyIdentifier(request); boolean ksEnabled = false; @@ -390,7 +422,21 @@ public class ExternSignServlet extends HttpServlet { } } - + if(manualPositioning) { + // store pdf data + // redirect to viewer html + String token = PdfAsHelper.storePdfData(pdfData, request); + + String pdfDataUrl = PdfAsHelper.generatePositioningURL(token, request, response); + + if(pdfDataUrl != null) { + response.sendRedirect(response.encodeRedirectURL(pdfDataUrl)); + return; + } else { + // remove Pdf data form session again! + PdfAsHelper.getPdfData(token, request); + } + } byte[] pdfSignedData = PdfAsHelper.synchornousSignature(request, response, pdfData); diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFPositioningDataServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFPositioningDataServlet.java new file mode 100644 index 00000000..95307c9c --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFPositioningDataServlet.java @@ -0,0 +1,70 @@ +package at.gv.egiz.pdfas.web.servlets; + +import java.io.IOException; +import java.io.OutputStream; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.web.helper.PdfAsHelper; + +public class PDFPositioningDataServlet extends HttpServlet { + + /** + * + */ + private static final long serialVersionUID = -8729046942909293640L; + + public static final String PARAM_TOKEN = "token"; + + private static final Logger logger = LoggerFactory + .getLogger(PDFPositioningDataServlet.class); + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse + * response) + */ + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + this.process(request, response); + } + + protected void process(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + try { + logger.debug("Access to pdf data"); + String token = request.getParameter(PARAM_TOKEN); + + if (token == null) { + logger.warn("No access token provided"); + throw new PdfAsException("No access token provided"); + } + + logger.debug("Access to pdf data with token: {}", token); + + byte[] pdfData = PdfAsHelper.getPdfData(request); + + if(pdfData == null) { + logger.warn("No PDF Data available or token does not match"); + throw new PdfAsException("No PDF Data available"); + } + + response.setContentType("application/pdf"); + OutputStream os = response.getOutputStream(); + os.write(pdfData); + os.close(); + } catch (Throwable e) { + PdfAsHelper.clearPdfData(request); + logger.error("Failed to access pdf data for positioning!"); + PdfAsHelper.setSessionException(request, response, e.getMessage(), + e); + PdfAsHelper.gotoError(getServletContext(), request, response); + } + } +} diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignNowServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignNowServlet.java new file mode 100644 index 00000000..58ce0167 --- /dev/null +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SignNowServlet.java @@ -0,0 +1,202 @@ +package at.gv.egiz.pdfas.web.servlets; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.pdfas.common.exceptions.PDFASError; +import at.gv.egiz.pdfas.web.config.WebConfiguration; +import at.gv.egiz.pdfas.web.exception.PdfAsWebException; +import at.gv.egiz.pdfas.web.helper.PdfAsHelper; +import at.gv.egiz.pdfas.web.helper.PdfAsParameterExtractor; +import at.gv.egiz.pdfas.web.stats.StatisticEvent; +import at.gv.egiz.pdfas.web.stats.StatisticFrontend; +import at.gv.egiz.pdfas.web.stats.StatisticEvent.Status; + +public class SignNowServlet extends HttpServlet { + + /** + * + */ + private static final long serialVersionUID = -8729046942909293640L; + + private static final Logger logger = LoggerFactory + .getLogger(SignNowServlet.class); + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse + * response) + */ + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + logger.debug("Get signing request"); + + StatisticEvent statisticEvent = PdfAsHelper.getStatisticEvent(request, + response); + + try { + this.process(request, response, statisticEvent); + } catch (Exception e) { + + statisticEvent.setStatus(Status.ERROR); + statisticEvent.setException(e); + if (e instanceof PDFASError) { + statisticEvent.setErrorCode(((PDFASError) e).getCode()); + } + statisticEvent.setEndNow(); + statisticEvent.setTimestampNow(); + StatisticFrontend.getInstance().storeEvent(statisticEvent); + statisticEvent.setLogged(true); + + PdfAsHelper.setSessionException(request, response, e.getMessage(), + e); + PdfAsHelper.gotoError(getServletContext(), request, response); + } + } + + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + logger.debug("Get signing request"); + + StatisticEvent statisticEvent = PdfAsHelper.getStatisticEvent(request, + response); + + try { + this.process(request, response, statisticEvent); + } catch (Exception e) { + + statisticEvent.setStatus(Status.ERROR); + statisticEvent.setException(e); + if (e instanceof PDFASError) { + statisticEvent.setErrorCode(((PDFASError) e).getCode()); + } + statisticEvent.setEndNow(); + statisticEvent.setTimestampNow(); + StatisticFrontend.getInstance().storeEvent(statisticEvent); + statisticEvent.setLogged(true); + + PdfAsHelper.setSessionException(request, response, e.getMessage(), + e); + PdfAsHelper.gotoError(getServletContext(), request, response); + } + } + + protected void process(HttpServletRequest request, + HttpServletResponse response, StatisticEvent statisticEvent) throws Exception { + + String connector = PdfAsHelper.getConnector(request); + + if (connector == null) { + connector = PdfAsParameterExtractor.getConnector(request); + } + + if (connector == null) { + throw new PdfAsWebException("No connector defined signature"); + } + + String transactionId = PdfAsHelper.getTransactionid(request); + + byte[] pdfData = PdfAsHelper.getPdfData(request); + + if (pdfData == null) { + throw new PdfAsWebException("No pdf data available"); + } + + PdfAsHelper.clearPdfData(request); + + String positioningString = PdfAsHelper.buildPosString(request, response); + logger.debug("Build position string: {}", positioningString); + + // IPlainSigner signer; + if (connector.equals("bku") || connector.equals("onlinebku") + || connector.equals("mobilebku")) { + // start asynchronous signature creation + + if (connector.equals("bku")) { + if (WebConfiguration.getLocalBKUURL() == null) { + throw new PdfAsWebException( + "Invalid connector bku is not supported"); + } + } + + if (connector.equals("onlinebku")) { + if (WebConfiguration.getLocalBKUURL() == null) { + throw new PdfAsWebException( + "Invalid connector onlinebku is not supported"); + } + } + + if (connector.equals("mobilebku")) { + if (WebConfiguration.getLocalBKUURL() == null) { + throw new PdfAsWebException( + "Invalid connector mobilebku is not supported"); + } + } + + PdfAsHelper.setStatisticEvent(request, response, statisticEvent); + + PdfAsHelper.startSignature(request, response, getServletContext(), + pdfData, connector, + positioningString, + transactionId, PdfAsHelper.getSignatureType(request), + PdfAsHelper.getPreProcessorMap(request), + PdfAsHelper.getOverwriteMap(request)); + return; + } else if (connector.equals("jks") || connector.equals("moa")) { + // start synchronous siganture creation + + if (connector.equals("jks")) { + + String keyIdentifier = PdfAsHelper.getKeyIdentifier(request); + + boolean ksEnabled = false; + + if (keyIdentifier != null) { + ksEnabled = WebConfiguration + .getKeystoreEnabled(keyIdentifier); + } else { + ksEnabled = WebConfiguration.getKeystoreDefaultEnabled(); + } + + if (!ksEnabled) { + if (keyIdentifier != null) { + throw new PdfAsWebException("JKS connector [" + + keyIdentifier + "] disabled or not existing."); + } else { + throw new PdfAsWebException( + "DEFAULT JKS connector disabled."); + } + } + } + + if (connector.equals("moa")) { + if (!WebConfiguration.getMOASSEnabled()) { + throw new PdfAsWebException( + "Invalid connector moa is not supported"); + } + } + + byte[] pdfSignedData = PdfAsHelper.synchornousSignature(request, + response, pdfData); + PdfAsHelper.setSignedPdf(request, response, pdfSignedData); + + statisticEvent.setStatus(Status.OK); + statisticEvent.setEndNow(); + statisticEvent.setTimestampNow(); + StatisticFrontend.getInstance().storeEvent(statisticEvent); + statisticEvent.setLogged(true); + + PdfAsHelper.gotoProvidePdf(getServletContext(), request, response); + return; + } else { + throw new PdfAsWebException("Invalid connector (bku | moa | jks)"); + } + + } +} diff --git a/pdf-as-web/src/main/webapp/WEB-INF/web.xml b/pdf-as-web/src/main/webapp/WEB-INF/web.xml index 4dd96f5f..3c80e11a 100644 --- a/pdf-as-web/src/main/webapp/WEB-INF/web.xml +++ b/pdf-as-web/src/main/webapp/WEB-INF/web.xml @@ -105,12 +105,24 @@ at.gv.egiz.pdfas.web.servlets.PDFData + + PDFPosData + PDFPosData + + at.gv.egiz.pdfas.web.servlets.PDFPositioningDataServlet + ErrorPage ErrorPage at.gv.egiz.pdfas.web.servlets.ErrorPage + + SIGNNOW + SIGNNOW + + at.gv.egiz.pdfas.web.servlets.SignNowServlet + PDFVerifyData PDFVerifyData @@ -181,6 +193,10 @@ PDFData /PDFData + + PDFPosData + /PDFPosData + ErrorPage /ErrorPage @@ -189,6 +205,10 @@ PDFVerifyData /signData + + SIGNNOW + /signNow + PDFVerifyCert /signCert diff --git a/pdf-as-web/src/main/webapp/assets/js/dragNdrop.js b/pdf-as-web/src/main/webapp/assets/js/dragNdrop.js index 940804bd..fd05f81b 100644 --- a/pdf-as-web/src/main/webapp/assets/js/dragNdrop.js +++ b/pdf-as-web/src/main/webapp/assets/js/dragNdrop.js @@ -111,7 +111,13 @@ function sign(file, connector, locale) { processData: false, contentType: false, type: "POST", + xhrFields: { + withCredentials: true + }, success: function(response) { + $("html").empty(); + $("html").html(response); + /* $("#fade").remove(); $("#popup").remove(); var fade_div = "
"; @@ -122,7 +128,7 @@ function sign(file, connector, locale) { $("#closelink").bind("click", function(evt) { $("#fade").remove(); $("#popup").remove(); - }); + });*/ } }); } diff --git a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/app.js b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/app.js index 6e16c306..da71e83d 100644 --- a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/app.js +++ b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/app.js @@ -12,7 +12,17 @@ function statusObject() { this.connector = null; this.file_path = null; this.file = null; - this.signature = null, + this.signature = null; + this.running = false; + this.applicationContext = '../../../../'; + + this.setRunning = function(r) { + this.running = (r === 'true'); + } + + this.getRunning = function() { + return this.running; + } this.setFile = function(f) { this.file = f; @@ -180,7 +190,7 @@ function isSignaturePlaced() { function placeSignature(evt, page_to_place, s) { var current_scale = PDFViewerApplication.pdfViewer.currentScale; var sig_size = Math.floor(96 * current_scale); - var defaultSignature = "Signature"; + var defaultSignature = "Signature"; if (typeof page_to_place === 'undefined') { page_to_place = PDFView.page;} if (typeof s === 'undefined') { s = defaultSignature} @@ -251,13 +261,15 @@ $(document).ready(function() { if(!results) { return null; } else { - return results[1] || 0; + return decodeURIComponent(results[1]) || decodeURI(0); } } global_status.setConnector($.urlParam("connector")); global_status.setPdfUlr($.urlParam("pdfurl")); global_status.setFilePath($.urlParam("file")); + console.log("Status:", global_status); + global_status.setRunning($.urlParam("running")); if(global_status.getFilePath()) { //if a filepath is given via the file HTML get parameter, try to fetch the file and display it fetchFile(global_status.getFilePath()).then(function(result) { @@ -370,11 +382,16 @@ function quickSign(connector, pdfurl) { fd.append("connector", connector); fd.append("pdf-url", pdfurl); + var signUrl = global_status.applicationContext + "/Sign"; + $.ajax({ - url: "/pdf-as-web/Sign", + url: signUrl, data: fd, processData: false, contentType: false, + xhrFields: { + withCredentials: true + }, type: "POST", success: function(response) { $("html").empty(); @@ -397,22 +414,44 @@ function sign(statusObj) { } var fd = new FormData(); fd.append("source", "internal"); - fd.append("connector", global_status.getConnector()); - fd.append("pdf-file", global_status.getFile()); - - if(isSignaturePlaced()) { - fd.append("sig-pos-x", global_status.getSignature().posx); - fd.append("sig-pos-y", global_status.getSignature().posy); - fd.append("sig-pos-p", global_status.getSignature().page); - } + var method = "POST"; + var signUrl = global_status.applicationContext + "/Sign"; + + if(global_status.getRunning()) { + signUrl = global_status.applicationContext + "/signNow"; + method = "GET"; + fd = null; + + if(isSignaturePlaced()) { + signUrl = signUrl + "?sigPosX=" + encodeURIComponent(global_status.getSignature().posx); + signUrl = signUrl + "&sigPosY=" + encodeURIComponent(global_status.getSignature().posy); + signUrl = signUrl + "&sigPosP=" + encodeURIComponent(global_status.getSignature().page); + } + } else { + fd.append("connector", global_status.getConnector()); + fd.append("pdf-file", global_status.getFile()); + if(isSignaturePlaced()) { + fd.append("sig-pos-x", global_status.getSignature().posx); + fd.append("sig-pos-y", global_status.getSignature().posy); + fd.append("sig-pos-p", global_status.getSignature().page); + } + } + + console.log("Data:", fd); $.ajax({ - url: "/pdf-as-web/Sign", + url: signUrl, data: fd, processData: false, contentType: false, - type: "POST", + type: method, + xhrFields: { + withCredentials: true + }, success: function(response) { + $("html").empty(); + $("html").html(response); + /* $("#fade").remove(); $("#popup").remove(); var fade_div = "
"; @@ -424,6 +463,9 @@ function sign(statusObj) { $("#fade").remove(); $("#popup").remove(); }); + if(typeof onAnmeldeSubmit == 'function') { + onAnmeldeSubmit(); + }*/ } }); } diff --git a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/images/signature-icon.png b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/images/signature-icon.png new file mode 100644 index 00000000..d47bc8a0 Binary files /dev/null and b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/images/signature-icon.png differ diff --git a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/images/signature-icon@2x.png b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/images/signature-icon@2x.png new file mode 100644 index 00000000..d47bc8a0 Binary files /dev/null and b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/images/signature-icon@2x.png differ diff --git a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.css b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.css index adba9ec6..de21f494 100644 --- a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.css +++ b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.css @@ -1052,6 +1052,11 @@ html[dir='rtl'] .toolbarButton.pageDown::before { content: url(images/toolbarButton-openFile.png); } +.toolbarButton.createSignature::before, +.secondaryToolbarButton.createSignature::before { + content: url(images/document_signature.png); +} + .toolbarButton.placeSignature::before, .secondaryToolbarButton.placeSignature::before { content: url(images/document_signature.png); diff --git a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.html b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.html index 6d49482d..c6cf575f 100644 --- a/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.html +++ b/pdf-as-web/src/main/webapp/assets/js/pdf.js/web/viewer.html @@ -31,7 +31,7 @@ http://sourceforge.net/adobe/cmap/wiki/License/ - + @@ -136,6 +136,11 @@ http://sourceforge.net/adobe/cmap/wiki/License/ Open + + +