aboutsummaryrefslogtreecommitdiff
path: root/pdf-as-web/src/main/java/at/gv
diff options
context:
space:
mode:
authorJakob Heher <jakob.heher@iaik.tugraz.at>2026-05-12 15:33:19 +0200
committerGitHub <noreply@github.com>2026-05-12 15:33:19 +0200
commitc8abbd8bef5349ab892a2853a4e5e3d5ed16b670 (patch)
tree04e86de8b547ac2685165cdf652b6c16355ae3c3 /pdf-as-web/src/main/java/at/gv
parente2bfdc313c0b6395d272624688b4ed1cba7ce967 (diff)
downloadpdf-as-4-c8abbd8bef5349ab892a2853a4e5e3d5ed16b670.tar.gz
pdf-as-4-c8abbd8bef5349ab892a2853a4e5e3d5ed16b670.tar.bz2
pdf-as-4-c8abbd8bef5349ab892a2853a4e5e3d5ed16b670.zip
Update docs & various fixes discovered in the process (#86)
- update documentation for pdf-as 5 - document the v2 json api - fix a number of documentation quirks - document `keyId` parameter - px (pixels) -> pt (pdf page units) - document --verify_level - remove a number of documented features that were never implemented: - `adobeSignFieldValue` and `sigLogoAltText` from signature profiles - `UNDERLINE` and `STRIKETHRU` from fonts - `num-bytes` parameter - `verify_only`/`sign_only` enable states for profiles - update mobile BKU base URL - update pdfbox backend default to 3 in sample configurations - consistently made boolean parsing from configuration files case permissive - add moa verification timeout - add support for BOLDITALIC to all base fonts, and for ITALIC to helvetica and courier - fix a number of small quirks - hibernate properties are now reloaded properly - fix the signature block parameter key regex - v1 json api now correctly checks for onlinebku/mobilebku being enabled - pdfbox 2 module correctly compares for integer equality regardless of cached boxed ints - test operationcountwatcher no longer sometimes breaks due to spring context differences
Diffstat (limited to 'pdf-as-web/src/main/java/at/gv')
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java142
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java33
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsParameterExtractor.java12
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/json_api/JacksonConfig.java8
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java5
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/JSONAPIServlet.java4
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/stats/impl/StatisticMicrometerBackend.java24
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASVerificationImpl.java6
8 files changed, 58 insertions, 176 deletions
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java
index 0b3fdf05..85e1b75d 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java
@@ -117,7 +117,7 @@ public class WebConfiguration implements IConfigurationConstants {
public static final String UPLOAD_FILESIZE_THRESHOLD = "web.upload.filesizeThreshold";
public static final String UPLOAD_MAX_FILESIZE = "web.upload.filesizeMax";
- public static final String UPLOAD_MAX_REQUESTSIZE = "web.upload.RequestsizeMax";
+ public static final String UPLOAD_MAX_REQUESTSIZE = "web.upload.requestsizeMax";
public static final String PLACEHOLDER_GENERATOR_ENABLED = "qr.placeholder.generator.enabled";
@@ -125,14 +125,14 @@ public class WebConfiguration implements IConfigurationConstants {
private static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB
private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB
- private static Properties properties = new Properties();
- private static Properties hibernateProps = new Properties();
+ private static final Properties properties = new Properties();
+ private static final Properties hibernateProps = new Properties();
private static final Logger logger = LoggerFactory
.getLogger(WebConfiguration.class);
- private static List<String> whiteListregEx = new ArrayList<String>();
- private static List<String> overwritewhiteListregEx = new ArrayList<String>();
+ private static final List<String> whiteListregEx = new ArrayList<String>();
+ private static final List<String> overwritewhiteListregEx = new ArrayList<String>();
public static void configure(String configFile) {
try (InputStream is = new FileInputStream(configFile)) {
@@ -145,6 +145,7 @@ public class WebConfiguration implements IConfigurationConstants {
public static void configure(InputStream config) {
properties.clear();
+ hibernateProps.clear();
whiteListregEx.clear();
overwritewhiteListregEx.clear();
@@ -324,12 +325,7 @@ public class WebConfiguration implements IConfigurationConstants {
public static boolean isAllowExtOverwrite() {
String value = properties.getProperty(ALLOW_EXT_OVERWRITE);
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(value);
}
public static synchronized boolean isOverwriteAllowed(String key) {
@@ -354,42 +350,22 @@ public class WebConfiguration implements IConfigurationConstants {
public static boolean isJSONAPIEnabled() {
String value = properties.getProperty(JSON_API_ENABLED);
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(value);
}
public static boolean isKeepSignedDocument() {
String value = properties.getProperty(KEEP_SIGNED_DOCUMENT);
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(value);
}
public static boolean isMoaEnabled(String keyIdentifier) {
String value = properties.getProperty(MOA_LIST + "." + keyIdentifier + ".enabled");
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(value);
}
public static boolean isQRPlaceholderGenerator() {
String value = properties.getProperty(PLACEHOLDER_GENERATOR_ENABLED);
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(value);
}
public static String getMoaURL(String keyIdentifier) {
@@ -443,121 +419,57 @@ public class WebConfiguration implements IConfigurationConstants {
public static boolean getMOASSEnabled() {
String value = properties.getProperty(MOA_SS_ENABLED);
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(value);
}
public static boolean getKeystoreDefaultEnabled() {
String value = properties.getProperty(KEYSTORE_DEFAULT_ENABLED);
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(value);
}
public static boolean getKeystoreEnabled(String keyIdentifier) {
String value = properties.getProperty(KEYSTORE_LIST + "." + keyIdentifier + "." + KEYSTORE_ENABLED);
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(value);
}
public static boolean getLocalBKUEnabled() {
- String value = properties.getProperty(LOCAL_BKU_ENABLED);
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(properties.getProperty(LOCAL_BKU_ENABLED));
}
public static boolean getMobileBKUEnabled() {
- String value = properties.getProperty(MOBILE_BKU_ENABLED);
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(properties.getProperty(MOBILE_BKU_ENABLED));
}
public static boolean getOnlineBKUEnabled() {
- String value = properties.getProperty(ONLINE_BKU_ENABLED);
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(properties.getProperty(ONLINE_BKU_ENABLED));
}
public static boolean getSL20Enabled() {
- String value = properties.getProperty(SL20_BKU_ENABLED);
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(properties.getProperty(SL20_BKU_ENABLED));
}
public static boolean getSoapSignEnabled() {
- String value = properties.getProperty(SOAP_SIGN_ENABLED);
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(properties.getProperty(SOAP_SIGN_ENABLED));
}
public static boolean isSoapSignWithVerifyEnabled() {
String value = properties.getProperty(SOAP_SIGN_WITH_VERIFY_ENABLED);
if (value != null) {
- return value.equals("true");
-
+ return Boolean.parseBoolean(value);
}
return getSoapSignEnabled();
}
public static boolean getSoapVerifyEnabled() {
- String value = properties.getProperty(SOAP_VERIFY_ENABLED);
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(properties.getProperty(SOAP_VERIFY_ENABLED));
}
public static boolean isShowErrorDetails() {
- String value = properties.getProperty(ERROR_DETAILS);
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(properties.getProperty(ERROR_DETAILS));
}
public static boolean isWhiteListEnabled() {
- String value = properties.getProperty(WHITELIST_ENABLED);
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(properties.getProperty(WHITELIST_ENABLED));
}
public static synchronized boolean isProvidePdfURLinWhitelist(String url) {
@@ -612,13 +524,7 @@ public class WebConfiguration implements IConfigurationConstants {
}
public static boolean getReloadEnabled() {
- String value = properties.getProperty(RELOAD_ENABLED);
- if (value != null) {
- if (value.equals("true")) {
- return true;
- }
- }
- return false;
+ return Boolean.parseBoolean(properties.getProperty(RELOAD_ENABLED));
}
public static int getFilesizeThreshold() {
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 95e9089f..4a4d15b2 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
@@ -181,33 +181,6 @@ public class PdfAsHelper {
return pdfAsConfig;
}
- private static void validatePdfSize(HttpServletRequest request,
- HttpServletResponse response, byte[] pdfData)
- throws PdfAsWebException {
- // Try to check num-bytes
- String pdfSizeString = PdfAsParameterExtractor.getNumBytes(request);
- if (pdfSizeString != null) {
- long pdfSize = -1;
- try {
- pdfSize = Long.parseLong(pdfSizeString);
- } catch (NumberFormatException e) {
- throw new PdfAsWebException(
- PdfAsParameterExtractor.PARAM_NUM_BYTES
- + " parameter has to be a positiv number!", e);
- }
- if (pdfSize <= 0) {
- throw new PdfAsWebException(
- "Invalid PDF Size! Has to bigger than zero!");
- }
-
- if (pdfData.length != pdfSize) {
- throw new PdfAsWebException("Signature Data Size and "
- + PdfAsParameterExtractor.PARAM_NUM_BYTES
- + " missmatch!");
- }
- }
- }
-
public static String buildPosString(HttpServletRequest request,
HttpServletResponse response) throws PdfAsWebException {
String posP = PdfAsParameterExtractor.getSigPosP(request);
@@ -270,19 +243,19 @@ public class PdfAsHelper {
sb.append("w:auto;");
}
}
- sb.append("w:" + posW.trim() + ";");
+ sb.append("w:").append(posW.trim()).append(";");
} else {
sb.append("w:auto;");
}
if (posP != null) {
- if (!(posP.equals("auto") || posP.equals("new"))) {
+ if (!(posP.equals("auto") || posP.equals("new") || posP.equals("last"))) {
try {
Integer.parseInt(posP);
} catch (NumberFormatException e) {
throw new PdfAsWebException(
PdfAsParameterExtractor.PARAM_SIG_POS_P
- + " has invalid value! (auto | new )");
+ + " has invalid value! (auto | new | last)");
}
}
sb.append("p:" + posP.trim() + ";");
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 0791e37e..ede5fdf5 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
@@ -41,7 +41,6 @@ public class PdfAsParameterExtractor {
public static final String PARAM_CONNECTOR = "connector";
public static final String PARAM_TRANSACTION_ID = "transactionId";
- public static final String PARAM_CONNECTOR_DEFAULT = "bku";
public static final String PARAM_FORMAT = "format";
public static final String PARAM_HTML = "html";
@@ -63,7 +62,6 @@ public class PdfAsParameterExtractor {
public static final String PARAM_VERIFY_LEVEL_OPTION_INT_ONLY = "intOnly";
public static final String PARAM_LOCALE = "locale";
- public static final String PARAM_NUM_BYTES = "num-bytes";
public static final String PARAM_PDF_URL = "pdf-url";
public static final String PARAM_SIG_TYPE = "sig-type";
public static final String PARAM_SIG_TYPE_ALIAS = "sig_type";
@@ -85,11 +83,7 @@ public class PdfAsParameterExtractor {
.getLogger(PdfAsParameterExtractor.class);
public static String getConnector(HttpServletRequest request) {
- String connector = (String)request.getAttribute(PARAM_CONNECTOR);
- if(connector != null) {
- return connector;
- }
- return PARAM_CONNECTOR_DEFAULT;
+ return (String)request.getAttribute(PARAM_CONNECTOR);
}
public static Map<String,String> getDynamicSignatureBlockParameters(HttpServletRequest request) throws Exception {
@@ -234,10 +228,6 @@ public class PdfAsParameterExtractor {
return null;
}
- public static String getNumBytes(HttpServletRequest request) {
- return (String)request.getAttribute(PARAM_NUM_BYTES);
- }
-
public static String getPdfUrl(HttpServletRequest request) {
return (String)request.getAttribute(PARAM_PDF_URL);
}
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/json_api/JacksonConfig.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/json_api/JacksonConfig.java
index bd82f8ed..ffb02c5f 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/json_api/JacksonConfig.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/json_api/JacksonConfig.java
@@ -2,6 +2,7 @@ package at.gv.egiz.pdfas.web.json_api;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationModule;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -16,4 +17,11 @@ public class JacksonConfig {
DeserializationFeature.READ_ENUMS_USING_TO_STRING
);
}
+
+ @Bean
+ public Jackson2ObjectMapperBuilderCustomizer useJaxbJsonNames() {
+ return b -> b.modulesToInstall(
+ new JakartaXmlBindAnnotationModule()
+ );
+ }
}
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 a28a4835..18754288 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
@@ -309,6 +309,9 @@ public class ExternSignServlet extends HttpServlet {
// Get Connector
String connector = PdfAsParameterExtractor.getConnector(request);
+ if (connector == null) {
+ throw new PdfAsException("No connector specified");
+ }
String transactionId = PdfAsParameterExtractor.getTransactionId(request);
@@ -460,7 +463,7 @@ public class ExternSignServlet extends HttpServlet {
return;
} else {
- throw new PdfAsWebException("Invalid connector (bku | moa | jks)");
+ throw new PdfAsWebException("Invalid connector (bku | moa | jks | onlinebku | mobilebku)");
}
}
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/JSONAPIServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/JSONAPIServlet.java
index b60fae06..f2c39a75 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/JSONAPIServlet.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/JSONAPIServlet.java
@@ -243,14 +243,14 @@ public class JSONAPIServlet extends HttpServlet {
}
if (PDFASSignParameters.Connector.ONLINEBKU.equals(connectorEnum)) {
- if (WebConfiguration.getLocalBKUURL() == null) {
+ if (WebConfiguration.getOnlineBKUURL() == null) {
throw new PdfAsWebException(
"Invalid connector onlinebku is not supported");
}
}
if (PDFASSignParameters.Connector.MOBILEBKU.equals(connectorEnum)) {
- if (WebConfiguration.getLocalBKUURL() == null) {
+ if (WebConfiguration.getHandyBKUURL() == null) {
throw new PdfAsWebException(
"Invalid connector mobilebku is not supported");
}
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/stats/impl/StatisticMicrometerBackend.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/stats/impl/StatisticMicrometerBackend.java
index 89127e6a..8b8fb489 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/stats/impl/StatisticMicrometerBackend.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/stats/impl/StatisticMicrometerBackend.java
@@ -7,30 +7,25 @@ import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tags;
import io.micrometer.core.instrument.Timer;
import lombok.extern.slf4j.Slf4j;
+import lombok.val;
import org.jspecify.annotations.NonNull;
import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
@Slf4j
public class StatisticMicrometerBackend implements StatisticBackend {
/** bridge between ServiceLoader component and Boot's beans */
@Component
- public static class SpringContextProxy implements ApplicationContextAware {
- private static volatile ApplicationContext applicationContext;
- @Override public void setApplicationContext(@NonNull ApplicationContext ctx) { applicationContext = ctx; }
- public static <T> T getBean(Class<T> type) {
- try {
- return (applicationContext != null) ? applicationContext.getBean(type) : null;
- } catch (BeansException ex) {
- log.warn("Spring MeterRegistry not available, skipped micrometer metric logging", ex);
- return null;
- }
- }
+ public static class SpringContextProxy {
+ public static MeterRegistry meterRegistry;
+ SpringContextProxy(MeterRegistry registry) { meterRegistry = registry; }
}
public static final String NAME = "StatisticMicrometerBackend";
@Override public String getName() { return NAME; }
@@ -39,8 +34,11 @@ public class StatisticMicrometerBackend implements StatisticBackend {
public void storeEvent(StatisticEvent e) {
if (e == null) return;
- MeterRegistry registry = SpringContextProxy.getBean(MeterRegistry.class);
- if (registry == null) return;
+ MeterRegistry registry = SpringContextProxy.meterRegistry;
+ if (registry == null) {
+ log.warn("Spring MeterRegistry not available, skipped micrometer metric logging");
+ return;
+ }
Tags baseTags = Tags.of(
"operation", safeName(e.getOperation(), v -> v.getName()),
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASVerificationImpl.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASVerificationImpl.java
index 68c5d227..1afd0c2d 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASVerificationImpl.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASVerificationImpl.java
@@ -69,7 +69,11 @@ public class PDFASVerificationImpl implements PDFASVerification {
}
statisticEvent.setFilesize(request.getInputData().length);
statisticEvent.setProfileId(null);
- statisticEvent.setDevice(request.getVerificationLevel().toString());
+ statisticEvent.setDevice(
+ (lvl == SignatureVerificationLevel.FULL_VERIFICATION ?
+ VerificationLevel.FULL_CERT_PATH :
+ VerificationLevel.INTEGRITY_ONLY)
+ .toString());
List<VerifyResult> results = PdfAsHelper.synchronousVerify(
request.getInputData(), sigIdx, lvl, preProcessor);