diff --git a/docs/sql/mysql/create-schema.sql b/docs/sql/mysql/create-schema.sql index af4d6293c..56696febc 100644 --- a/docs/sql/mysql/create-schema.sql +++ b/docs/sql/mysql/create-schema.sql @@ -34,6 +34,7 @@ CREATE TABLE es_onboarding_process ( activation_id VARCHAR(36), status VARCHAR(32) NOT NULL, error_detail VARCHAR(256), + error_origin VARCHAR(256), error_score INTEGER NOT NULL DEFAULT 0, timestamp_created DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, timestamp_last_updated DATETIME, @@ -52,6 +53,7 @@ CREATE TABLE es_onboarding_otp ( status VARCHAR(32) NOT NULL, type VARCHAR(32) NOT NULL, error_detail VARCHAR(256), + error_origin VARCHAR(256), failed_attempts INTEGER, timestamp_created DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, timestamp_expiration DATETIME NOT NULL, @@ -73,7 +75,9 @@ CREATE TABLE es_identity_verification ( status VARCHAR(32) NOT NULL, phase VARCHAR(32) NOT NULL, reject_reason TEXT, + reject_origin VARCHAR(256), error_detail VARCHAR(256), + error_origin VARCHAR(256), session_info TEXT, timestamp_created DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, timestamp_last_updated DATETIME, @@ -101,7 +105,9 @@ CREATE TABLE es_document_verification ( photo_id VARCHAR(256), verification_score INTEGER, reject_reason TEXT, + reject_origin VARCHAR(256), error_detail VARCHAR(256), + error_origin VARCHAR(256), original_document_id VARCHAR(36), used_for_verification TINYINT DEFAULT 0, timestamp_created DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -136,8 +142,10 @@ CREATE TABLE es_document_result ( document_verification_id VARCHAR(36) NOT NULL, phase VARCHAR(32) NOT NULL, reject_reason TEXT, + reject_origin VARCHAR(256), verification_result TEXT, error_detail TEXT, + error_origin VARCHAR(256), extracted_data TEXT, timestamp_created DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (document_verification_id) REFERENCES es_document_verification (id) diff --git a/docs/sql/oracle/create-schema.sql b/docs/sql/oracle/create-schema.sql index ba81dbc42..79f4fb907 100644 --- a/docs/sql/oracle/create-schema.sql +++ b/docs/sql/oracle/create-schema.sql @@ -37,6 +37,7 @@ CREATE TABLE ES_ONBOARDING_PROCESS ( ACTIVATION_ID VARCHAR2(36 CHAR), STATUS VARCHAR2(32 CHAR) NOT NULL, ERROR_DETAIL VARCHAR2(256 CHAR), + ERROR_ORIGIN VARCHAR2(256 CHAR), ERROR_SCORE INTEGER DEFAULT 0 NOT NULL, TIMESTAMP_CREATED TIMESTAMP(6) NOT NULL, TIMESTAMP_LAST_UPDATED TIMESTAMP(6), @@ -55,6 +56,7 @@ CREATE TABLE ES_ONBOARDING_OTP ( STATUS VARCHAR2(32 CHAR) NOT NULL, TYPE VARCHAR2(32 CHAR) NOT NULL, ERROR_DETAIL VARCHAR2(256 CHAR), + ERROR_ORIGIN VARCHAR2(256 CHAR), FAILED_ATTEMPTS INTEGER, TIMESTAMP_CREATED TIMESTAMP(6) NOT NULL, TIMESTAMP_EXPIRATION TIMESTAMP(6) NOT NULL, @@ -77,7 +79,9 @@ CREATE TABLE ES_IDENTITY_VERIFICATION ( STATUS VARCHAR2(32 CHAR) NOT NULL, PHASE VARCHAR2(32 CHAR) NOT NULL, REJECT_REASON CLOB, + REJECT_ORIGIN VARCHAR2(256 CHAR), ERROR_DETAIL VARCHAR2(256 CHAR), + ERROR_ORIGIN VARCHAR2(256 CHAR), SESSION_INFO CLOB, TIMESTAMP_CREATED TIMESTAMP(6) NOT NULL, TIMESTAMP_LAST_UPDATED TIMESTAMP(6), @@ -105,7 +109,9 @@ CREATE TABLE ES_DOCUMENT_VERIFICATION ( PHOTO_ID VARCHAR2(256 CHAR), VERIFICATION_SCORE INTEGER, REJECT_REASON CLOB, + REJECT_ORIGIN VARCHAR2(256 CHAR), ERROR_DETAIL VARCHAR2(256 CHAR), + ERROR_ORIGIN VARCHAR2(256 CHAR), ORIGINAL_DOCUMENT_ID VARCHAR2(36 CHAR), USED_FOR_VERIFICATION NUMBER(1) DEFAULT 0, TIMESTAMP_CREATED TIMESTAMP(6) NOT NULL, @@ -141,8 +147,10 @@ CREATE TABLE ES_DOCUMENT_RESULT ( DOCUMENT_VERIFICATION_ID VARCHAR2(36 CHAR) NOT NULL, PHASE VARCHAR2(32 CHAR) NOT NULL, REJECT_REASON CLOB, + REJECT_ORIGIN VARCHAR2(256 CHAR), VERIFICATION_RESULT CLOB, ERROR_DETAIL CLOB, + ERROR_ORIGIN VARCHAR2(256 CHAR), EXTRACTED_DATA CLOB, TIMESTAMP_CREATED TIMESTAMP(6) NOT NULL, FOREIGN KEY (DOCUMENT_VERIFICATION_ID) REFERENCES ES_DOCUMENT_VERIFICATION (ID) diff --git a/docs/sql/postgresql/create-schema.sql b/docs/sql/postgresql/create-schema.sql index 2e737dee1..ca14ab6f4 100644 --- a/docs/sql/postgresql/create-schema.sql +++ b/docs/sql/postgresql/create-schema.sql @@ -41,6 +41,7 @@ CREATE TABLE es_onboarding_process ( activation_id VARCHAR(36), status VARCHAR(32) NOT NULL, error_detail VARCHAR(256), + error_origin VARCHAR(256), error_score INTEGER NOT NULL DEFAULT 0, timestamp_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, timestamp_last_updated TIMESTAMP, @@ -59,6 +60,7 @@ CREATE TABLE es_onboarding_otp ( status VARCHAR(32) NOT NULL, type VARCHAR(32) NOT NULL, error_detail VARCHAR(256), + error_origin VARCHAR(256), failed_attempts INTEGER, timestamp_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, timestamp_expiration TIMESTAMP NOT NULL, @@ -81,7 +83,9 @@ CREATE TABLE es_identity_verification ( status VARCHAR(32) NOT NULL, phase VARCHAR(32) NOT NULL, reject_reason TEXT, + reject_origin VARCHAR(256), error_detail VARCHAR(256), + error_origin VARCHAR(256), session_info TEXT, timestamp_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, timestamp_last_updated TIMESTAMP, @@ -109,7 +113,9 @@ CREATE TABLE es_document_verification ( photo_id VARCHAR(256), verification_score INTEGER, reject_reason TEXT, + reject_origin VARCHAR(256), error_detail VARCHAR(256), + error_origin VARCHAR(256), original_document_id VARCHAR(36), used_for_verification BOOLEAN DEFAULT FALSE, timestamp_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -145,8 +151,10 @@ CREATE TABLE es_document_result ( document_verification_id VARCHAR(36) NOT NULL, phase VARCHAR(32) NOT NULL, reject_reason TEXT, + reject_origin VARCHAR(256), verification_result TEXT, error_detail TEXT, + error_origin VARCHAR(256), extracted_data TEXT, timestamp_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (document_verification_id) REFERENCES es_document_verification (id) diff --git a/enrollment-server-domain-model/src/main/java/com/wultra/app/enrollmentserver/model/enumeration/ErrorOrigin.java b/enrollment-server-domain-model/src/main/java/com/wultra/app/enrollmentserver/model/enumeration/ErrorOrigin.java new file mode 100644 index 000000000..e0f95dc15 --- /dev/null +++ b/enrollment-server-domain-model/src/main/java/com/wultra/app/enrollmentserver/model/enumeration/ErrorOrigin.java @@ -0,0 +1,37 @@ +/* + * PowerAuth Enrollment Server + * Copyright (C) 2022 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.app.enrollmentserver.model.enumeration; + +/** + * Origin of an error enumeration. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +public enum ErrorOrigin { + + DOCUMENT_VERIFICATION, + + PRESENCE_CHECK, + + OTP_VERIFICATION, + + PROCESS_LIMIT_CHECK, + + USER_REQUEST + +} diff --git a/enrollment-server-domain-model/src/main/java/com/wultra/app/enrollmentserver/model/enumeration/RejectOrigin.java b/enrollment-server-domain-model/src/main/java/com/wultra/app/enrollmentserver/model/enumeration/RejectOrigin.java new file mode 100644 index 000000000..90f41e2a9 --- /dev/null +++ b/enrollment-server-domain-model/src/main/java/com/wultra/app/enrollmentserver/model/enumeration/RejectOrigin.java @@ -0,0 +1,31 @@ +/* + * PowerAuth Enrollment Server + * Copyright (C) 2022 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.app.enrollmentserver.model.enumeration; + +/** + * Origin of a rejection enumeration. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +public enum RejectOrigin { + + DOCUMENT_VERIFICATION, + + PRESENCE_CHECK + +} diff --git a/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/database/entity/OnboardingOtpEntity.java b/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/database/entity/OnboardingOtpEntity.java index 7a31015e6..e53482e76 100644 --- a/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/database/entity/OnboardingOtpEntity.java +++ b/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/database/entity/OnboardingOtpEntity.java @@ -18,6 +18,7 @@ package com.wultra.app.onboardingserver.common.database.entity; +import com.wultra.app.enrollmentserver.model.enumeration.ErrorOrigin; import com.wultra.app.enrollmentserver.model.enumeration.OtpStatus; import com.wultra.app.enrollmentserver.model.enumeration.OtpType; import lombok.Getter; @@ -74,6 +75,10 @@ public class OnboardingOtpEntity implements Serializable { @Column(name = "error_detail") private String errorDetail; + @Column(name = "error_origin") + @Enumerated(EnumType.STRING) + private ErrorOrigin errorOrigin; + @Column(name = "failed_attempts") private int failedAttempts; diff --git a/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/database/entity/OnboardingProcessEntity.java b/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/database/entity/OnboardingProcessEntity.java index 7e3e50140..7ec0a4c0a 100644 --- a/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/database/entity/OnboardingProcessEntity.java +++ b/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/database/entity/OnboardingProcessEntity.java @@ -18,6 +18,7 @@ package com.wultra.app.onboardingserver.common.database.entity; +import com.wultra.app.enrollmentserver.model.enumeration.ErrorOrigin; import com.wultra.app.enrollmentserver.model.enumeration.OnboardingStatus; import lombok.Getter; import lombok.NoArgsConstructor; @@ -77,6 +78,10 @@ public class OnboardingProcessEntity implements Serializable { @Column(name = "error_detail") private String errorDetail; + @Column(name = "error_origin") + @Enumerated(EnumType.STRING) + private ErrorOrigin errorOrigin; + @Column(name = "error_score") private int errorScore; diff --git a/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/service/CommonOtpService.java b/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/service/CommonOtpService.java index 638cbe924..20768a590 100644 --- a/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/service/CommonOtpService.java +++ b/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/service/CommonOtpService.java @@ -18,6 +18,7 @@ package com.wultra.app.onboardingserver.common.service; import com.wultra.app.enrollmentserver.api.model.onboarding.response.OtpVerifyResponse; +import com.wultra.app.enrollmentserver.model.enumeration.ErrorOrigin; import com.wultra.app.enrollmentserver.model.enumeration.OnboardingStatus; import com.wultra.app.enrollmentserver.model.enumeration.OtpStatus; import com.wultra.app.enrollmentserver.model.enumeration.OtpType; @@ -94,12 +95,13 @@ public OtpVerifyResponse verifyOtpCode(String processId, String otpCode, OtpType logger.warn("Unexpected not active {}, process ID: {}", otp, processId); } else if (failedAttempts >= maxFailedAttempts) { logger.warn("Unexpected OTP code verification when already exhausted max failed attempts, process ID: {}", processId); - process = processLimitService.failProcess(process, OnboardingOtpEntity.ERROR_MAX_FAILED_ATTEMPTS); + process = processLimitService.failProcess(process, OnboardingOtpEntity.ERROR_MAX_FAILED_ATTEMPTS, ErrorOrigin.PROCESS_LIMIT_CHECK); } else if (otp.hasExpired()) { logger.info("Expired OTP code received, process ID: {}", processId); expired = true; otp.setStatus(OtpStatus.FAILED); otp.setErrorDetail(OnboardingOtpEntity.ERROR_EXPIRED); + otp.setErrorOrigin(ErrorOrigin.OTP_VERIFICATION); otp.setTimestampLastUpdated(now); onboardingOtpRepository.save(otp); } else if (otp.getOtpCode().equals(otpCode)) { @@ -138,10 +140,11 @@ private void handleFailedOtpVerification(OnboardingProcessEntity process, Onboar if (failedAttempts >= maxFailedAttempts) { otp.setStatus(OtpStatus.FAILED); otp.setErrorDetail(OnboardingOtpEntity.ERROR_MAX_FAILED_ATTEMPTS); + otp.setErrorOrigin(ErrorOrigin.OTP_VERIFICATION); onboardingOtpRepository.save(otp); // Onboarding process is failed, update it - process = processLimitService.failProcess(process, OnboardingOtpEntity.ERROR_MAX_FAILED_ATTEMPTS); + process = processLimitService.failProcess(process, OnboardingOtpEntity.ERROR_MAX_FAILED_ATTEMPTS, ErrorOrigin.PROCESS_LIMIT_CHECK); } else { // Increase error score for process based on OTP type if (otpType == OtpType.ACTIVATION) { @@ -156,6 +159,7 @@ private void handleFailedOtpVerification(OnboardingProcessEntity process, Onboar if (process.getStatus() == OnboardingStatus.FAILED) { otp.setStatus(OtpStatus.FAILED); otp.setErrorDetail(process.getErrorDetail()); + otp.setErrorOrigin(ErrorOrigin.OTP_VERIFICATION); onboardingOtpRepository.save(otp); } } diff --git a/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/service/CommonProcessLimitService.java b/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/service/CommonProcessLimitService.java index a536cce8b..20fc5de43 100644 --- a/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/service/CommonProcessLimitService.java +++ b/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/service/CommonProcessLimitService.java @@ -17,6 +17,7 @@ */ package com.wultra.app.onboardingserver.common.service; +import com.wultra.app.enrollmentserver.model.enumeration.ErrorOrigin; import com.wultra.app.enrollmentserver.model.enumeration.OnboardingStatus; import com.wultra.app.onboardingserver.common.configuration.CommonOnboardingConfig; import com.wultra.app.onboardingserver.common.database.OnboardingProcessRepository; @@ -71,7 +72,7 @@ public OnboardingProcessEntity checkOnboardingProcessErrorLimits(OnboardingProce int maxProcessErrorScore = config.getMaxProcessErrorScore(); if (process.getErrorScore() > maxProcessErrorScore) { // Onboarding process is failed, update it and persist the change - process = failProcess(process, OnboardingProcessEntity.ERROR_MAX_PROCESS_ERROR_SCORE_EXCEEDED); + process = failProcess(process, OnboardingProcessEntity.ERROR_MAX_PROCESS_ERROR_SCORE_EXCEEDED, ErrorOrigin.PROCESS_LIMIT_CHECK); } return process; } @@ -84,7 +85,7 @@ public OnboardingProcessEntity checkOnboardingProcessErrorLimits(OnboardingProce * @param errorDetail Error detail. * @return Updated onboarding process entity. */ - public OnboardingProcessEntity failProcess(OnboardingProcessEntity entity, String errorDetail) { + public OnboardingProcessEntity failProcess(OnboardingProcessEntity entity, String errorDetail, ErrorOrigin errorOrigin) { if (OnboardingStatus.FAILED == entity.getStatus()) { logger.debug("Not failing already failed onboarding entity ID: {}", entity.getId()); return entity; @@ -92,6 +93,7 @@ public OnboardingProcessEntity failProcess(OnboardingProcessEntity entity, Strin entity.setStatus(OnboardingStatus.FAILED); entity.setTimestampLastUpdated(new Date()); entity.setErrorDetail(errorDetail); + entity.setErrorOrigin(errorOrigin); return onboardingProcessRepository.save(entity); } diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/database/entity/DocumentResultEntity.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/database/entity/DocumentResultEntity.java index fca47152a..891176cd6 100644 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/database/entity/DocumentResultEntity.java +++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/database/entity/DocumentResultEntity.java @@ -19,6 +19,8 @@ package com.wultra.app.onboardingserver.database.entity; import com.wultra.app.enrollmentserver.model.enumeration.DocumentProcessingPhase; +import com.wultra.app.enrollmentserver.model.enumeration.ErrorOrigin; +import com.wultra.app.enrollmentserver.model.enumeration.RejectOrigin; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -74,6 +76,13 @@ public class DocumentResultEntity implements Serializable { @Lob private String rejectReason; + /** + * Origin of rejection + */ + @Column(name = "reject_origin") + @Enumerated(EnumType.STRING) + private RejectOrigin rejectOrigin; + /** * JSON serialized document with the verification result */ @@ -88,6 +97,10 @@ public class DocumentResultEntity implements Serializable { @Lob private String errorDetail; + @Column(name = "error_origin") + @Enumerated(EnumType.STRING) + private ErrorOrigin errorOrigin; + /** * JSON serialized data extracted from the uploaded document */ diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/database/entity/DocumentVerificationEntity.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/database/entity/DocumentVerificationEntity.java index 1affb6c5d..3f6cf76b7 100644 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/database/entity/DocumentVerificationEntity.java +++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/database/entity/DocumentVerificationEntity.java @@ -18,9 +18,7 @@ package com.wultra.app.onboardingserver.database.entity; -import com.wultra.app.enrollmentserver.model.enumeration.CardSide; -import com.wultra.app.enrollmentserver.model.enumeration.DocumentStatus; -import com.wultra.app.enrollmentserver.model.enumeration.DocumentType; +import com.wultra.app.enrollmentserver.model.enumeration.*; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -141,12 +139,26 @@ public class DocumentVerificationEntity implements Serializable { @Lob private String rejectReason; + /** + * Origin of rejection + */ + @Column(name = "reject_origin") + @Enumerated(EnumType.STRING) + private RejectOrigin rejectOrigin; + /** * Overall error detail in case a generic error occurred */ @Column(name = "error_detail") private String errorDetail; + /** + * Origin of an error + */ + @Column(name = "error_origin") + @Enumerated(EnumType.STRING) + private ErrorOrigin errorOrigin; + /** * Identifier of an entity which was replaced by this entity */ diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/database/entity/IdentityVerificationEntity.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/database/entity/IdentityVerificationEntity.java index 94a537669..999703de3 100644 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/database/entity/IdentityVerificationEntity.java +++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/database/entity/IdentityVerificationEntity.java @@ -18,8 +18,10 @@ package com.wultra.app.onboardingserver.database.entity; +import com.wultra.app.enrollmentserver.model.enumeration.ErrorOrigin; import com.wultra.app.enrollmentserver.model.enumeration.IdentityVerificationPhase; import com.wultra.app.enrollmentserver.model.enumeration.IdentityVerificationStatus; +import com.wultra.app.enrollmentserver.model.enumeration.RejectOrigin; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -77,9 +79,17 @@ public class IdentityVerificationEntity implements Serializable { @Lob private String rejectReason; + @Column(name = "reject_origin") + @Enumerated(EnumType.STRING) + private RejectOrigin rejectOrigin; + @Column(name = "error_detail") private String errorDetail; + @Column(name = "error_origin") + @Enumerated(EnumType.STRING) + private ErrorOrigin errorOrigin; + @Column(name = "session_info") @Lob private String sessionInfo; diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/docverify/zenid/provider/ZenidDocumentVerificationProvider.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/docverify/zenid/provider/ZenidDocumentVerificationProvider.java index 690a89ae7..f0eaeead0 100644 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/docverify/zenid/provider/ZenidDocumentVerificationProvider.java +++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/docverify/zenid/provider/ZenidDocumentVerificationProvider.java @@ -35,6 +35,7 @@ import com.wultra.app.onboardingserver.errorhandling.DocumentVerificationException; import com.wultra.app.onboardingserver.provider.DocumentVerificationProvider; import com.wultra.core.rest.client.base.RestClientException; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -537,7 +538,7 @@ private DocumentsVerificationResult toResult(OwnerId id, ZenidWebInvestigateResp // Check the results if there is no rejected validation Optional optionalFailedVerification = result.getResults() .stream() - .filter(value -> value.getRejectReason() != null) + .filter(value -> StringUtils.isNotBlank(value.getRejectReason())) .findAny(); if (optionalFailedVerification.isPresent()) { verificationStatus = DocumentVerificationStatus.REJECTED; diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/ClientEvaluationService.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/ClientEvaluationService.java index 6ab631407..d50547ffd 100644 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/ClientEvaluationService.java +++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/ClientEvaluationService.java @@ -18,6 +18,7 @@ package com.wultra.app.onboardingserver.impl.service; import com.wultra.app.enrollmentserver.model.enumeration.DocumentStatus; +import com.wultra.app.enrollmentserver.model.enumeration.ErrorOrigin; import com.wultra.app.enrollmentserver.model.enumeration.IdentityVerificationPhase; import com.wultra.app.enrollmentserver.model.enumeration.IdentityVerificationStatus; import com.wultra.app.enrollmentserver.model.integration.OwnerId; @@ -146,6 +147,7 @@ private Consumer createErrorConsumer(final IdentityVerificationEntity logger.debug("Client evaluation failed for {}", identityVerification, t); identityVerification.setStatus(IdentityVerificationStatus.FAILED); identityVerification.setErrorDetail(IdentityVerificationEntity.ERROR_MAX_FAILED_ATTEMPTS_CLIENT_EVALUATION); + identityVerification.setErrorOrigin(ErrorOrigin.PROCESS_LIMIT_CHECK); saveInTransaction(identityVerification); }; } diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/IdentityVerificationLimitService.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/IdentityVerificationLimitService.java index f53485024..1a8035cab 100644 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/IdentityVerificationLimitService.java +++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/IdentityVerificationLimitService.java @@ -20,6 +20,7 @@ package com.wultra.app.onboardingserver.impl.service; import com.wultra.app.enrollmentserver.model.enumeration.DocumentStatus; +import com.wultra.app.enrollmentserver.model.enumeration.ErrorOrigin; import com.wultra.app.enrollmentserver.model.enumeration.IdentityVerificationStatus; import com.wultra.app.enrollmentserver.model.enumeration.OnboardingStatus; import com.wultra.app.enrollmentserver.model.integration.OwnerId; @@ -106,6 +107,7 @@ public void checkIdentityVerificationLimit(OwnerId ownerId) throws RemoteCommuni final OnboardingProcessEntity onboardingProcess = onboardingProcessOptional.get(); onboardingProcess.setErrorDetail(OnboardingProcessEntity.ERROR_MAX_FAILED_ATTEMPTS_IDENTITY_VERIFICATION); + onboardingProcess.setErrorOrigin(ErrorOrigin.PROCESS_LIMIT_CHECK); onboardingProcess.setStatus(OnboardingStatus.FAILED); onboardingProcessRepository.save(onboardingProcess); @@ -130,6 +132,7 @@ public void checkDocumentUploadLimit(OwnerId ownerId, IdentityVerificationEntity if (documentVerificationsFailed.size() > identityVerificationConfig.getDocumentUploadMaxFailedAttempts()) { identityVerification.setStatus(IdentityVerificationStatus.FAILED); identityVerification.setErrorDetail(IdentityVerificationEntity.ERROR_MAX_FAILED_ATTEMPTS_DOCUMENT_UPLOAD); + identityVerification.setErrorOrigin(ErrorOrigin.PROCESS_LIMIT_CHECK); identityVerificationRepository.save(identityVerification); identityVerificationResetService.resetIdentityVerification(ownerId); logger.warn("Max failed attempts reached for document upload, {}.", ownerId); diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/IdentityVerificationOtpService.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/IdentityVerificationOtpService.java index 27a67bf19..f7a6de167 100644 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/IdentityVerificationOtpService.java +++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/IdentityVerificationOtpService.java @@ -176,9 +176,12 @@ private OtpVerifyResponse verifyPresenceCheck(final OnboardingProcessEntity proc final IdentityVerificationEntity idVerification = getIdentityVerificationEntity(process); final String errorDetail = idVerification.getErrorDetail(); + final ErrorOrigin errorOrigin = idVerification.getErrorOrigin(); final String rejectReason = idVerification.getRejectReason(); + final RejectOrigin rejectOrigin = idVerification.getRejectOrigin(); - if (StringUtils.isNotBlank(errorDetail) || StringUtils.isNotBlank(rejectReason)) { + if (errorOrigin == ErrorOrigin.PRESENCE_CHECK && StringUtils.isNotBlank(errorDetail) + || rejectOrigin == RejectOrigin.PRESENCE_CHECK && StringUtils.isNotBlank(rejectReason)) { logger.info("SCA failed, IdentityVerification ID: {} of Process ID: {} contains errorDetail: {}, rejectReason: {} from previous step", idVerification.getId(), processId, errorDetail, rejectReason); return moveToPhasePresenceCheck(process, response, idVerification); @@ -202,7 +205,9 @@ private OtpVerifyResponse moveToPhasePresenceCheck( idVerification.setStatus(IdentityVerificationStatus.NOT_INITIALIZED); idVerification.setTimestampLastUpdated(new Date()); idVerification.setErrorDetail(null); + idVerification.setErrorOrigin(null); idVerification.setRejectReason(null); + idVerification.setRejectOrigin(null); identityVerificationRepository.save(idVerification); logger.info("Switched to PRESENCE_CHECK/NOT_INITIALIZED, process ID: {}", idVerification.getProcessId()); @@ -221,6 +226,7 @@ private void markVerificationOtpAsFailed(String processId) throws OnboardingProc new OnboardingProcessException("Onboarding OTP not found, process ID: " + processId)); otp.setStatus(OtpStatus.FAILED); otp.setErrorDetail(OnboardingOtpEntity.ERROR_CANCELED); + otp.setErrorOrigin(ErrorOrigin.OTP_VERIFICATION); otp.setTimestampLastUpdated(new Date()); onboardingOtpRepository.save(otp); } diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/IdentityVerificationService.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/IdentityVerificationService.java index e221daf95..471e393cc 100644 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/IdentityVerificationService.java +++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/IdentityVerificationService.java @@ -21,10 +21,7 @@ import com.wultra.app.enrollmentserver.api.model.onboarding.request.DocumentSubmitRequest; import com.wultra.app.enrollmentserver.api.model.onboarding.response.DocumentStatusResponse; import com.wultra.app.enrollmentserver.api.model.onboarding.response.data.DocumentMetadataResponseDto; -import com.wultra.app.enrollmentserver.model.enumeration.DocumentStatus; -import com.wultra.app.enrollmentserver.model.enumeration.DocumentType; -import com.wultra.app.enrollmentserver.model.enumeration.IdentityVerificationPhase; -import com.wultra.app.enrollmentserver.model.enumeration.IdentityVerificationStatus; +import com.wultra.app.enrollmentserver.model.enumeration.*; import com.wultra.app.enrollmentserver.model.integration.DocumentsVerificationResult; import com.wultra.app.enrollmentserver.model.integration.Image; import com.wultra.app.enrollmentserver.model.integration.OwnerId; @@ -45,6 +42,7 @@ import com.wultra.app.onboardingserver.impl.service.document.DocumentProcessingService; import com.wultra.app.onboardingserver.impl.service.verification.VerificationProcessingService; import com.wultra.app.onboardingserver.provider.DocumentVerificationProvider; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -362,6 +360,7 @@ private void resolveIdentityVerificationResult( idVerification.setPhase(phase); idVerification.setStatus(IdentityVerificationStatus.FAILED); idVerification.setErrorDetail(failed.getErrorDetail()); + idVerification.setErrorOrigin(ErrorOrigin.DOCUMENT_VERIFICATION); }); docVerifications.stream() @@ -371,6 +370,7 @@ private void resolveIdentityVerificationResult( idVerification.setPhase(phase); idVerification.setStatus(IdentityVerificationStatus.REJECTED); idVerification.setErrorDetail(failed.getRejectReason()); + idVerification.setErrorOrigin(ErrorOrigin.DOCUMENT_VERIFICATION); }); } } @@ -568,7 +568,7 @@ private List collectRejectionErrors(DocumentVerificationEntity entity) { private DocumentMetadataResponseDto toDocumentMetadata(DocumentVerificationEntity entity) { DocumentMetadataResponseDto docMetadata = new DocumentMetadataResponseDto(); docMetadata.setId(entity.getId()); - if (entity.getErrorDetail() != null) { + if (StringUtils.isNotBlank(entity.getErrorDetail())) { docMetadata.setErrors(List.of(entity.getErrorDetail())); } docMetadata.setFilename(entity.getFilename()); diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/OnboardingServiceImpl.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/OnboardingServiceImpl.java index bbc77547d..5e67a22bb 100644 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/OnboardingServiceImpl.java +++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/OnboardingServiceImpl.java @@ -21,6 +21,7 @@ import com.wultra.app.enrollmentserver.api.model.onboarding.response.OnboardingConsentTextResponse; import com.wultra.app.enrollmentserver.api.model.onboarding.response.OnboardingStartResponse; import com.wultra.app.enrollmentserver.api.model.onboarding.response.OnboardingStatusResponse; +import com.wultra.app.enrollmentserver.model.enumeration.ErrorOrigin; import com.wultra.app.enrollmentserver.model.enumeration.OnboardingStatus; import com.wultra.app.enrollmentserver.model.enumeration.OtpType; import com.wultra.app.enrollmentserver.model.integration.OwnerId; @@ -141,6 +142,7 @@ public OnboardingStartResponse startOnboarding(OnboardingStartRequest request) t if (existingProcessCount > onboardingConfig.getMaxProcessCountPerDay()) { process.setStatus(OnboardingStatus.FAILED); process.setErrorDetail(OnboardingProcessEntity.ERROR_TOO_MANY_PROCESSES_PER_USER); + process.setErrorOrigin(ErrorOrigin.PROCESS_LIMIT_CHECK); onboardingProcessRepository.save(process); logger.warn("Maximum number of processes per day reached for user: {}", userId); throw new TooManyProcessesException(); @@ -250,6 +252,7 @@ public Response performCleanup(OnboardingCleanupRequest request) throws Onboardi process.setStatus(OnboardingStatus.FAILED); process.setTimestampLastUpdated(new Date()); process.setErrorDetail(OnboardingProcessEntity.ERROR_PROCESS_CANCELED); + process.setErrorOrigin(ErrorOrigin.USER_REQUEST); onboardingProcessRepository.save(process); return new Response(); } diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/OtpServiceImpl.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/OtpServiceImpl.java index 3d06b844d..8cd8245b2 100644 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/OtpServiceImpl.java +++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/OtpServiceImpl.java @@ -17,6 +17,7 @@ */ package com.wultra.app.onboardingserver.impl.service; +import com.wultra.app.enrollmentserver.model.enumeration.ErrorOrigin; import com.wultra.app.enrollmentserver.model.enumeration.OtpStatus; import com.wultra.app.enrollmentserver.model.enumeration.OtpType; import com.wultra.app.onboardingserver.common.database.OnboardingOtpRepository; @@ -133,6 +134,7 @@ public void cancelOtp(OnboardingProcessEntity process, OtpType otpType) { otp.setStatus(OtpStatus.FAILED); otp.setTimestampLastUpdated(new Date()); otp.setErrorDetail(OnboardingOtpEntity.ERROR_CANCELED); + otp.setErrorOrigin(ErrorOrigin.OTP_VERIFICATION); onboardingOtpRepository.save(otp); } } diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/PresenceCheckLimitService.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/PresenceCheckLimitService.java index 8c4ab62fa..7130bde4b 100644 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/PresenceCheckLimitService.java +++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/PresenceCheckLimitService.java @@ -19,6 +19,7 @@ package com.wultra.app.onboardingserver.impl.service; +import com.wultra.app.enrollmentserver.model.enumeration.ErrorOrigin; import com.wultra.app.enrollmentserver.model.enumeration.IdentityVerificationStatus; import com.wultra.app.enrollmentserver.model.enumeration.OnboardingStatus; import com.wultra.app.enrollmentserver.model.enumeration.OtpType; @@ -106,10 +107,12 @@ public void checkPresenceCheckMaxAttemptLimit(OwnerId ownerId, String processId) identityVerification.setStatus(IdentityVerificationStatus.FAILED); identityVerification.setErrorDetail(IdentityVerificationEntity.ERROR_MAX_FAILED_ATTEMPTS_PRESENCE_CHECK); + identityVerification.setErrorOrigin(ErrorOrigin.PROCESS_LIMIT_CHECK); identityVerificationRepository.save(identityVerification); final OnboardingProcessEntity onboardingProcess = onboardingProcessOptional.get(); onboardingProcess.setErrorDetail(IdentityVerificationEntity.ERROR_MAX_FAILED_ATTEMPTS_PRESENCE_CHECK); + onboardingProcess.setErrorOrigin(ErrorOrigin.PROCESS_LIMIT_CHECK); onboardingProcess.setStatus(OnboardingStatus.FAILED); onboardingProcessRepository.save(onboardingProcess); diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/PresenceCheckService.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/PresenceCheckService.java index 4e7807695..1f613dd44 100644 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/PresenceCheckService.java +++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/PresenceCheckService.java @@ -19,10 +19,7 @@ import com.google.common.base.Ascii; import com.google.common.base.Preconditions; -import com.wultra.app.enrollmentserver.model.enumeration.DocumentType; -import com.wultra.app.enrollmentserver.model.enumeration.IdentityVerificationPhase; -import com.wultra.app.enrollmentserver.model.enumeration.IdentityVerificationStatus; -import com.wultra.app.enrollmentserver.model.enumeration.PresenceCheckStatus; +import com.wultra.app.enrollmentserver.model.enumeration.*; import com.wultra.app.enrollmentserver.model.integration.*; import com.wultra.app.onboardingserver.configuration.IdentityVerificationConfig; import com.wultra.app.onboardingserver.database.DocumentVerificationRepository; @@ -271,6 +268,7 @@ private void evaluatePresenceCheckResult(OwnerId ownerId, break; case FAILED: idVerification.setErrorDetail(result.getErrorDetail()); + idVerification.setErrorOrigin(ErrorOrigin.PRESENCE_CHECK); idVerification.setStatus(IdentityVerificationStatus.FAILED); idVerification.setTimestampLastUpdated(ownerId.getTimestamp()); logger.warn("Presence check failed, {}, errorDetail: '{}'", ownerId, result.getErrorDetail()); @@ -280,6 +278,7 @@ private void evaluatePresenceCheckResult(OwnerId ownerId, break; case REJECTED: idVerification.setRejectReason(result.getRejectReason()); + idVerification.setRejectOrigin(RejectOrigin.PRESENCE_CHECK); idVerification.setStatus(IdentityVerificationStatus.REJECTED); idVerification.setTimestampLastUpdated(ownerId.getTimestamp()); logger.info("Presence check rejected, {}, rejectReason: '{}'", ownerId, result.getRejectReason()); diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/document/DocumentProcessingService.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/document/DocumentProcessingService.java index 9cf878689..1f727e094 100644 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/document/DocumentProcessingService.java +++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/document/DocumentProcessingService.java @@ -20,9 +20,7 @@ import com.wultra.app.enrollmentserver.api.model.onboarding.request.DocumentSubmitRequest; import com.wultra.app.enrollmentserver.model.Document; import com.wultra.app.enrollmentserver.model.DocumentMetadata; -import com.wultra.app.enrollmentserver.model.enumeration.DocumentProcessingPhase; -import com.wultra.app.enrollmentserver.model.enumeration.DocumentStatus; -import com.wultra.app.enrollmentserver.model.enumeration.DocumentType; +import com.wultra.app.enrollmentserver.model.enumeration.*; import com.wultra.app.enrollmentserver.model.integration.*; import com.wultra.app.onboardingserver.configuration.IdentityVerificationConfig; import com.wultra.app.onboardingserver.database.DocumentDataRepository; @@ -36,6 +34,7 @@ import com.wultra.app.onboardingserver.errorhandling.DocumentVerificationException; import com.wultra.app.onboardingserver.impl.service.DataExtractionService; import com.wultra.app.onboardingserver.provider.DocumentVerificationProvider; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -126,6 +125,7 @@ public List submitDocuments( } catch (DocumentSubmitException e) { docVerification.setStatus(DocumentStatus.FAILED); docVerification.setErrorDetail(e.getMessage()); + docVerification.setErrorOrigin(ErrorOrigin.DOCUMENT_VERIFICATION); return docVerifications; } @@ -199,9 +199,16 @@ public void checkDocumentSubmitWithProvider(OwnerId ownerId, DocumentResultEntit docSubmitResult.setErrorDetail(e.getMessage()); } - documentResultEntity.setErrorDetail(docSubmitResult.getErrorDetail()); + if (StringUtils.isNotBlank(docSubmitResult.getErrorDetail())) { + documentResultEntity.setErrorDetail(docSubmitResult.getErrorDetail()); + documentResultEntity.setErrorOrigin(ErrorOrigin.DOCUMENT_VERIFICATION); + } + if (StringUtils.isNotBlank(docSubmitResult.getRejectReason())) { + documentResultEntity.setRejectReason(docSubmitResult.getRejectReason()); + documentResultEntity.setRejectOrigin(RejectOrigin.DOCUMENT_VERIFICATION); + } + documentResultEntity.setExtractedData(docSubmitResult.getExtractedData()); - documentResultEntity.setRejectReason(docSubmitResult.getRejectReason()); processDocsSubmitResults(ownerId, docVerification, docsSubmitResults, docSubmitResult); } @@ -287,9 +294,11 @@ private DocumentResultEntity createDocumentResult( DocumentSubmitResult docSubmitResult) { DocumentResultEntity entity = new DocumentResultEntity(); entity.setErrorDetail(docVerificationEntity.getErrorDetail()); + entity.setErrorOrigin(docVerificationEntity.getErrorOrigin()); entity.setExtractedData(docSubmitResult.getExtractedData()); entity.setPhase(DocumentProcessingPhase.UPLOAD); entity.setRejectReason(docVerificationEntity.getRejectReason()); + entity.setRejectOrigin(docVerificationEntity.getRejectOrigin()); return entity; } @@ -366,12 +375,14 @@ private List getDocuments(OwnerId ownerId, DocumentSubmitRequest reque private void processDocsSubmitResults(OwnerId ownerId, DocumentVerificationEntity docVerification, DocumentsSubmitResult docsSubmitResults, DocumentSubmitResult docSubmitResult) { - if (docSubmitResult.getErrorDetail() != null) { + if (StringUtils.isNotBlank(docSubmitResult.getErrorDetail())) { docVerification.setStatus(DocumentStatus.FAILED); docVerification.setErrorDetail(docSubmitResult.getErrorDetail()); - } else if (docSubmitResult.getRejectReason() != null) { + docVerification.setErrorOrigin(ErrorOrigin.DOCUMENT_VERIFICATION); + } else if (StringUtils.isNotBlank(docSubmitResult.getRejectReason())) { docVerification.setStatus(DocumentStatus.REJECTED); docVerification.setRejectReason(docSubmitResult.getRejectReason()); + docVerification.setRejectOrigin(RejectOrigin.DOCUMENT_VERIFICATION); } else { docVerification.setPhotoId(docsSubmitResults.getExtractedPhotoId()); docVerification.setProviderName(identityVerificationConfig.getDocumentVerificationProvider()); @@ -406,6 +417,7 @@ private void verifyDocumentWithUpload(OwnerId ownerId, DocumentVerificationEntit logger.warn("Unable to verify document with uploadId: {}, reason: {}, {}", uploadId, e.getMessage(), ownerId); docVerification.setStatus(DocumentStatus.FAILED); docVerification.setErrorDetail(e.getMessage()); + docVerification.setErrorOrigin(ErrorOrigin.DOCUMENT_VERIFICATION); } } diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/verification/VerificationProcessingService.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/verification/VerificationProcessingService.java index ff7bd0301..01ebaff4d 100644 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/verification/VerificationProcessingService.java +++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/verification/VerificationProcessingService.java @@ -17,18 +17,16 @@ */ package com.wultra.app.onboardingserver.impl.service.verification; +import com.wultra.app.enrollmentserver.model.enumeration.*; import com.wultra.app.onboardingserver.database.DocumentResultRepository; import com.wultra.app.onboardingserver.database.DocumentVerificationRepository; import com.wultra.app.onboardingserver.database.entity.DocumentResultEntity; import com.wultra.app.onboardingserver.database.entity.DocumentVerificationEntity; import com.wultra.app.onboardingserver.errorhandling.DocumentVerificationException; -import com.wultra.app.enrollmentserver.model.enumeration.DocumentProcessingPhase; -import com.wultra.app.enrollmentserver.model.enumeration.DocumentStatus; -import com.wultra.app.enrollmentserver.model.enumeration.DocumentVerificationStatus; -import com.wultra.app.enrollmentserver.model.enumeration.IdentityVerificationPhase; import com.wultra.app.enrollmentserver.model.integration.DocumentVerificationResult; import com.wultra.app.enrollmentserver.model.integration.DocumentsVerificationResult; import com.wultra.app.enrollmentserver.model.integration.OwnerId; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -169,10 +167,12 @@ private void updateDocVerification(OwnerId ownerId, DocumentVerificationEntity d case FAILED: docVerification.setStatus(DocumentStatus.FAILED); docVerification.setErrorDetail(docVerificationResult.getErrorDetail()); + docVerification.setErrorOrigin(ErrorOrigin.DOCUMENT_VERIFICATION); break; case REJECTED: docVerification.setStatus(DocumentStatus.REJECTED); docVerification.setRejectReason(docVerificationResult.getRejectReason()); + docVerification.setRejectOrigin(RejectOrigin.DOCUMENT_VERIFICATION); break; default: throw new IllegalStateException("Unexpected verification result status: " + docVerificationResult.getStatus()); @@ -187,8 +187,13 @@ private void updateDocVerification(OwnerId ownerId, DocumentVerificationEntity d */ private void updateDocumentResult(DocumentResultEntity docResult, DocumentVerificationResult docVerificationResult) { - docResult.setErrorDetail(docVerificationResult.getErrorDetail()); - docResult.setRejectReason(docVerificationResult.getRejectReason()); + if (StringUtils.isNotBlank(docResult.getErrorDetail())) { + docResult.setErrorDetail(docVerificationResult.getErrorDetail()); + docResult.setErrorOrigin(ErrorOrigin.DOCUMENT_VERIFICATION); + } else if (StringUtils.isNotBlank(docResult.getRejectReason())) { + docResult.setRejectReason(docVerificationResult.getRejectReason()); + docResult.setRejectOrigin(RejectOrigin.DOCUMENT_VERIFICATION); + } docResult.setVerificationResult(docVerificationResult.getVerificationResult()); } diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/statemachine/action/presencecheck/PresenceCheckVerificationAction.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/statemachine/action/presencecheck/PresenceCheckVerificationAction.java index d25fb22d9..021c2d593 100644 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/statemachine/action/presencecheck/PresenceCheckVerificationAction.java +++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/statemachine/action/presencecheck/PresenceCheckVerificationAction.java @@ -16,6 +16,7 @@ */ package com.wultra.app.onboardingserver.statemachine.action.presencecheck; +import com.wultra.app.enrollmentserver.model.enumeration.ErrorOrigin; import com.wultra.app.enrollmentserver.model.enumeration.IdentityVerificationStatus; import com.wultra.app.enrollmentserver.model.integration.OwnerId; import com.wultra.app.enrollmentserver.model.integration.SessionInfo; @@ -64,6 +65,7 @@ public void execute(StateContext context) { if (sessionInfo == null) { logger.error("Checking presence verification failed due to invalid session info, {}", ownerId); identityVerification.setErrorDetail("Unable to deserialize session info"); + identityVerification.setErrorOrigin(ErrorOrigin.PRESENCE_CHECK); identityVerification.setStatus(IdentityVerificationStatus.FAILED); identityVerification.setTimestampLastUpdated(ownerId.getTimestamp()); } else { @@ -72,6 +74,7 @@ public void execute(StateContext context) { } catch (PresenceCheckException e) { logger.error("Checking presence verification failed, {}", ownerId, e); identityVerification.setErrorDetail(e.getMessage()); + identityVerification.setErrorOrigin(ErrorOrigin.PRESENCE_CHECK); identityVerification.setStatus(IdentityVerificationStatus.FAILED); identityVerification.setTimestampLastUpdated(ownerId.getTimestamp()); }