diff options
| author | Jakob Heher <jakob.heher@iaik.tugraz.at> | 2026-05-12 15:33:19 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-05-12 15:33:19 +0200 |
| commit | c8abbd8bef5349ab892a2853a4e5e3d5ed16b670 (patch) | |
| tree | 04e86de8b547ac2685165cdf652b6c16355ae3c3 /pdf-as-web/src/main/java/at/gv | |
| parent | e2bfdc313c0b6395d272624688b4ed1cba7ce967 (diff) | |
| download | pdf-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')
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); |
