From 977501479f3be3110af5be3681b7b11dc1837e95 Mon Sep 17 00:00:00 2001 From: mahammedtaheer <57249563+mahammedtaheer@users.noreply.github.com> Date: Mon, 11 Sep 2023 16:20:26 +0530 Subject: [PATCH] Merge develop to Release 1.2.0.1 (#1090) * MOSIP-26891 added condition in caching (#1045) Co-authored-by: Neha Farheen * Mosip 26891 caches in ida module should avoid caching null values (#1046) * MOSIP-26891 added condition in caching * modified the conditions --------- Co-authored-by: Neha Farheen * Mosip 26891 caches in ida module should avoid caching null values (#1047) * MOSIP-26891 added condition in caching * modified the conditions * condition changed --------- Co-authored-by: Neha Farheen * Mosip 26891 caches in ida module should avoid caching null values (#1048) * MOSIP-26891 added condition in caching * modified the conditions * condition changed * condition changed --------- Co-authored-by: Neha Farheen * Mosip 26891 caches in ida module should avoid caching null values (#1049) * MOSIP-26891 added condition in caching * modified the conditions * condition changed * condition changed * condition changed --------- Co-authored-by: Neha Farheen * [BUGFIX] [ES-176] Handles the scenario when no claims are accepted from a set of optional claims sub parameter is added to consented claim by default if it is emptywq * iat validation corrected * [MOSIP-28622] fixed firstname, lastname not populating in e-signet issue. * [MOSIP-28484] Added error handling for deploy.sh script (#1061) * [MOSIP-28484] Added error handling for deploy.sh script * [MOSIP-28484] Updated error handling for deploy.sh script * [MOSIP-28484] Removed exit command --------- Co-authored-by: akilalakshmanan * Implemented the VCI plugin in IDA * Format the code * Changes done * Changes done * Changes done * Decrypted the individualId * [ES-186] Added new Vci Exchange API to add support for VCI. * Added new repo for LD signature library. (#1075) * updated push trigger to include settings.xml for sonar analysis and fixed start up error. * removed show progress argument for wget command to display download progress. * ES-107 * Fixed the cache read issue * ES-187 * ES-187 * [ES-186] Fixed integration issues. * ES-187 * [ES-186] changed the VC ID to UUID instead of PSUT and added locales. * [MOSIP-29163] updated reusable workflows (#1088) * merge from release-1.2.0.1 to develop (#1089) * [MOSIP-21002] Updated kyc error response to have kycStatus and updated db scripts (#872) * Update 1.2_ida-scripts_release.sql (#852) * [MOSIP-21072] Fixed db scripts for upgrade (#865) * [MOSIP-18655] reverted EnvUtil as RefreshScope * [MOSIP-18655] Ignoring test cases temporarily * [MOSIP-18655] Updated EnvUtil to implement env methods * [MOSIP-18655] Ignoring test cases temporarily * [MOSIP-18655] Ignoring test cases temporarily * [MOSIP-18655] reverted EnvUtil as RefreshScope * [MOSIP-18655] reverted EnvUtil as RefreshScope * [MOSIP-18655] Updated EnvUtil to implement env methods * [MOSIP-18655] reverted EnvUtil as RefreshScope * [MOSIP-18655] Updated EnvUtil to implement env methods * [MOSIP-18655] reverted EnvUtil as RefreshScope * [MOSIP-18655] Updated EnvUtil to implement env methods * [MOSIP-18655] reverted EnvUtil as RefreshScope * [MOSIP-18655] Updated EnvUtil to implement env methods * [MOSIP-21072] Fixed db scripts for upgrade * [MOSIP-21002] Updated kyc error response to have kycStatus (#868) * Revert "[MOSIP-21072] Fixed db scripts for upgrade (#865)" (#869) This reverts commit bed76a2ddce57a407a174fd6d682b946cb2b220f. * [MOSIP-21002] Updated kyc error response to have kycStatus and updated db release scripts (#871) * Revert "[MOSIP-21072] Fixed db scripts for upgrade (#865)" This reverts commit bed76a2ddce57a407a174fd6d682b946cb2b220f. * [MOSIP-21072] reverted release script changes * [MOSIP-21072] reverted release script changes * Revert "[MOSIP-21072] reverted release script changes" This reverts commit 4cbb9899f3acc69c3383b339176937ebb1877b0e. * [MOSIP-21072] updated db release scripts (#873) * Revert "[MOSIP-21072] Fixed db scripts for upgrade (#865)" This reverts commit bed76a2ddce57a407a174fd6d682b946cb2b220f. * [MOSIP-21072] reverted release script changes * [MOSIP-21072] reverted release script changes * Revert "[MOSIP-21072] reverted release script changes" This reverts commit 4cbb9899f3acc69c3383b339176937ebb1877b0e. * [MOSIP-21072] updated db release scripts * [MOSIP-21072] Updated exception handling for ekyc (#874) * Revert "[MOSIP-21072] Fixed db scripts for upgrade (#865)" This reverts commit bed76a2ddce57a407a174fd6d682b946cb2b220f. * [MOSIP-21072] reverted release script changes * [MOSIP-21072] reverted release script changes * Revert "[MOSIP-21072] reverted release script changes" This reverts commit 4cbb9899f3acc69c3383b339176937ebb1877b0e. * [MOSIP-21072] updated db release scripts * [MOSIP-21072] Fixed test case * [MOSIP-20984] added support for bio type to be case insensitive (#875) * Revert "[MOSIP-21072] Fixed db scripts for upgrade (#865)" This reverts commit bed76a2ddce57a407a174fd6d682b946cb2b220f. * [MOSIP-21072] reverted release script changes * [MOSIP-21072] reverted release script changes * Revert "[MOSIP-21072] reverted release script changes" This reverts commit 4cbb9899f3acc69c3383b339176937ebb1877b0e. * [MOSIP-21072] updated db release scripts * [MOSIP-21072] Fixed test case * [MOSIP-20984] added support for bio type to be case insensitive Co-authored-by: Loganathan Sekar <42532387+LoganathanSekar7627@users.noreply.github.com> * [MOSIP-20020] Update release_changes.yml * [ MOSIP-20021 ] updated release_changes.yml to update README.md badges * [MOSIP-20028] added action for tagging * Added pre-expire-days & access-allowed values in DB release script. (#897) * release file name changes. * MOSIP-23611- Added flag to enable missing credential retrigger. Disabled by default * Added logger * release file name changes. * release file name changes. * Test case fix * Release Bot Pre-release changes * Update README.md * updated snapshot url in push_trigger.yaml * Added auth context class in internal and otp service, renamed the db script files. * Removed not null constraint to policy id and added kycexchange exception handler. * [DSD-1944] updated keymanager version * updated sonar token * Release Bot Pre-release changes * Update README.md * Code from develop branch. (#1000) * resolved merge conflicts. * [MOSIP-20020] Update release_changes.yml * [ MOSIP-20021 ] updated release_changes.yml to update README.md badges * [MOSIP-20028] added action for tagging * Added pre-expire-days & access-allowed values in DB release script. (#897) * release file name changes. * Added auth context class in internal and otp service, renamed the db script files. * removed not null constraint for policy_id in misp license data. * [DSD-1935]added new token to check sonar_token functionality * [DSD-1935]Updated sonar token * MOSIP-25606 Fixed OIDC Client create/update and corrected address claim attributes. * Added audit entry for kyc exchange and updated idhash in audit entry instead of individual id. * Fixed bugs MOSIP-25718, MOSIP-25717 add opencv jar file for image conversion performance. * Fixed test case. * MOSIP-25757: Created esignet-integration-impl * Removed mock implementations * Changed class name * Changed package name * Changed esignet dependency scope * Added ignore on failed test cases * Added new Identity key binding API in ida service. * MOSIP-25855: Added getAllKycSigningCertificates * Added default values * Removed Authentication Header * Added test classes * Modified test cases * MOSIP-25324 * Added tables in ddl.sql * [MOSIP-25637] Updated postgres-init_trigger.yml workflow (#965) * [MOSIP-25637] Updated postgres-init_trigger.yml workflow * Update postgres-init_trigger.yml * [MOSIP-25637] Updated postgres-init_trigger.yml workflow (#966) * Changes in biomatcher Util for unknown data (#971) Co-authored-by: Neha Farheen * Mosip 26307 change in ida to correct bio sub type value sent in the match request (#972) * Changes in biomatcher Util for unknown data * Bug fixed --------- Co-authored-by: Neha Farheen Co-authored-by: Loganathan Sekar <42532387+LoganathanSekar7627@users.noreply.github.com> * MOSIP-26295: Auditor implementation * MOSIP-25867 * fixed application start error. * MOSIP-26484 * Fixed test case failures * Fixed couple of bugs. Jira # MOSIP-26472, MOSIP-26028. * Renamed TokenInfo to KeyBindedToken * MOSIP-26484 * MOSIP-26484 * Added workaround for key binded auth. * Fixed test case failure error. * MOSIP-26484 (#985) Co-authored-by: ase-101 <> * Fixed audit caching issue * Update AuthTransactionHelper.java * Fixed auditing error * Added Key Binded Token authentication functionality. * ignoring the failed test case temporarily. * Corrected the header names * Corrected the header names * MOSIP-25324 * MOSIP-25324 * MOSIP-25324 * MOSIP-25324 * Changed kycStatus to bindingAuthStatus * Added debug statement. * Fixed issue in comparing the time difference. * DB changes added in release db scripts * Updating certificate to all VIDs for same TokenId and changed logic in fetching the binded certificates. --------- Co-authored-by: Keshav Mishra Co-authored-by: syed-salman-technoforte Co-authored-by: kameshsr Co-authored-by: Mahesh-Binayak <76687012+Mahesh-Binayak@users.noreply.github.com> Co-authored-by: M1044292 Co-authored-by: ase-101 <> Co-authored-by: Mohan E Co-authored-by: Neha2365 <110969715+Neha2365@users.noreply.github.com> Co-authored-by: Neha Farheen Co-authored-by: Loganathan Sekar <42532387+LoganathanSekar7627@users.noreply.github.com> Co-authored-by: Anusha Sunkada Co-authored-by: Himaja Dhanyamraju <43470317+HimajaDhanyamraju2@users.noreply.github.com> * updated snapshot url (#1001) * Corrected the upgrade scripts name (#1002) Co-authored-by: ase-101 <> * Release changes (#1004) * Release Bot Pre-release changes * Update README.md --------- Co-authored-by: ckm007 * [DSD-2478] (#1005) * MOSIP-26742 hash logic compatibility release 1201 (#1007) MOSIP-26742 * Added support for legacy method of hashing * Handled salt missing when newhash calculation * Review comment fixes * Updated conditions and added logging --------- Co-authored-by: Loganathan Sekar * Mosip 26742 hash logic compatibility 1 (#1008) * Added support for legacy method of hashing * Test fixes * Handled salt missing when newhash calculation * Review comment fixes * Updated conditions and added logging * Fixed value annotation --------- Co-authored-by: Loganathan Sekar * [MOSIP-23422] updated db_release scripts (#1022) * [MOSIP-27964] updated upgrade sql's * [MOSIP-27964] Update 1.1.5.5_to_1.2.0.1-B1_upgrade.sql (#1032) Signed-off-by: Keshav Mishra * [MOSIP-27964] * [MOSIP-27996] updated rollback sql * [MOSIP-23218] Updated Pom.xml versions. (#1035) * Updated versions to -SNAPSHOT * Updated version to 1.2.0.1-SNAPSHOT * Test fix * [MOSIP-28175]Fixed publish to nexus failure * Fix to salt caching issue * Revert "Include new class from keymanager in imports." This reverts commit 17a2375f82350d9d3a8f3dea26c0bfc3c5fa90a5. * Revert "Added functionality in kyc-exchange API to return response in encrypted form (JWE).MOSIP-25369" This reverts commit ec22724905a167052da7156aa15438efd8058792. * Removed sysadmin * Corrected user * MOSIP-28227 Moved ddl script into upgrade scripts, corrections to upgrade scripts * Added placeholder scripts for upgrade * Jira No. MOSIP-28227, removed the truncate previledge for 3 tables and drop key_policy_def_h table. (#1053) * [MOSIP-28622] fixed firstname, lastname not populating in e-signet issue. * Reverted dependencies snapshot versions (#1059) Co-authored-by: Loganathan Sekar * Fix compilation issue after snapshot version revert. (#1060) * Reverted dependencies snapshot versions * Fixed compilation issue --------- Co-authored-by: Loganathan Sekar * Release changes (#1063) * Release Bot Pre-release changes * Update README.md Signed-off-by: Keshav Mishra --------- Signed-off-by: Keshav Mishra Co-authored-by: ckm007 * Release 1.2.0.1 b4 (#1064) * Reverted dependencies snapshot versions (#1059) Co-authored-by: Loganathan Sekar * Fix compilation issue after snapshot version revert. (#1060) * Reverted dependencies snapshot versions * Fixed compilation issue --------- Co-authored-by: Loganathan Sekar * Release changes (#1063) * Release Bot Pre-release changes * Update README.md Signed-off-by: Keshav Mishra --------- Signed-off-by: Keshav Mishra Co-authored-by: ckm007 * Update pom.xml Signed-off-by: Keshav Mishra * Update pom.xml Signed-off-by: Keshav Mishra * Update pom.xml Signed-off-by: Keshav Mishra * Update push_trigger.yml Signed-off-by: Keshav Mishra * Update pom.xml Signed-off-by: Keshav Mishra * Update pom.xml Signed-off-by: Keshav Mishra * Update pom.xml Signed-off-by: Keshav Mishra * Update pom.xml Signed-off-by: Keshav Mishra * Update pom.xml Signed-off-by: Keshav Mishra * Update pom.xml Signed-off-by: Keshav Mishra * Update pom.xml Signed-off-by: Keshav Mishra * Update pom.xml Signed-off-by: Keshav Mishra * Update pom.xml Signed-off-by: Keshav Mishra * Update pom.xml Signed-off-by: Keshav Mishra * Update pom.xml Signed-off-by: Keshav Mishra * Update pom.xml Signed-off-by: Keshav Mishra * Update pom.xml Signed-off-by: Keshav Mishra * Update pom.xml Signed-off-by: Keshav Mishra --------- Signed-off-by: Keshav Mishra Co-authored-by: Loganathan Sekar <42532387+LoganathanSekar7627@users.noreply.github.com> Co-authored-by: Loganathan Sekar Co-authored-by: ckm007 * [MOSIP-29044] (#1067) * Rename 1.2.0.1-B3_to_1.2.0.1_rollback.sql to 1.2.0.1-B3_to_1.2.0.1-B4_rollback.sql Signed-off-by: Keshav Mishra * Rename 1.2.0.1-B3_to_1.2.0.1_upgrade.sql to 1.2.0.1-B3_to_1.2.0.1-B4_upgrade.sql Signed-off-by: Keshav Mishra * Create 1.2.0.1-B4_to_1.2.0.1_rollback.sql Signed-off-by: Keshav Mishra * Create Create 1.2.0.1-B4_to_1.2.0.1_upgrade.sql Signed-off-by: Keshav Mishra * Rename Create 1.2.0.1-B4_to_1.2.0.1_upgrade.sql to 1.2.0.1-B4_to_1.2.0.1_upgrade.sql Signed-off-by: Keshav Mishra --------- Signed-off-by: Keshav Mishra * [MOSIP-28484] Added error handling for deploy.sh script (#1065) Co-authored-by: akilalakshmanan * Update push_trigger.yml Signed-off-by: Keshav Mishra * WIP-Changes to allow available otp channel * PSA-171 fix for allowing one of the available channels when both channels specified. * Updated the pom versions * Fix to have case insensitive check for channel attribute --------- Signed-off-by: Keshav Mishra Co-authored-by: Manoj SP <43261486+manojsp12@users.noreply.github.com> Co-authored-by: Loganathan Sekar <42532387+LoganathanSekar7627@users.noreply.github.com> Co-authored-by: Keshav Mishra Co-authored-by: syed-salman-technoforte <72004356+syed-salman-technoforte@users.noreply.github.com> Co-authored-by: syed-salman-technoforte Co-authored-by: kameshsr Co-authored-by: Loganathan Sekar Co-authored-by: pramod444 Co-authored-by: syed salman <72004356+syedsalman3753@users.noreply.github.com> Co-authored-by: ckm007 Co-authored-by: Mahesh-Binayak <76687012+Mahesh-Binayak@users.noreply.github.com> Co-authored-by: M1044292 Co-authored-by: Mohan E Co-authored-by: Neha2365 <110969715+Neha2365@users.noreply.github.com> Co-authored-by: Neha Farheen Co-authored-by: Anusha Sunkada Co-authored-by: Himaja Dhanyamraju <43470317+HimajaDhanyamraju2@users.noreply.github.com> Co-authored-by: Loganathan Sekar Co-authored-by: Vishwa Co-authored-by: Rakshitha650 <76676196+Rakshitha650@users.noreply.github.com> Co-authored-by: Akila Lakshmanan <77330852+akilalakshmanan@users.noreply.github.com> Co-authored-by: akilalakshmanan --------- Signed-off-by: Keshav Mishra Co-authored-by: Neha2365 <110969715+Neha2365@users.noreply.github.com> Co-authored-by: Neha Farheen Co-authored-by: Hitesh Jain Co-authored-by: Vishwa Co-authored-by: anshulv1401 Co-authored-by: Akila Lakshmanan <77330852+akilalakshmanan@users.noreply.github.com> Co-authored-by: akilalakshmanan Co-authored-by: ase-101 <> Co-authored-by: bhumi46 <111699703+bhumi46@users.noreply.github.com> Co-authored-by: Manoj SP <43261486+manojsp12@users.noreply.github.com> Co-authored-by: Loganathan Sekar <42532387+LoganathanSekar7627@users.noreply.github.com> Co-authored-by: Keshav Mishra Co-authored-by: syed-salman-technoforte <72004356+syed-salman-technoforte@users.noreply.github.com> Co-authored-by: syed-salman-technoforte Co-authored-by: kameshsr Co-authored-by: Loganathan Sekar Co-authored-by: pramod444 Co-authored-by: syed salman <72004356+syedsalman3753@users.noreply.github.com> Co-authored-by: ckm007 Co-authored-by: Mahesh-Binayak <76687012+Mahesh-Binayak@users.noreply.github.com> Co-authored-by: M1044292 Co-authored-by: Mohan E Co-authored-by: Anusha Sunkada Co-authored-by: Himaja Dhanyamraju <43470317+HimajaDhanyamraju2@users.noreply.github.com> Co-authored-by: Loganathan Sekar Co-authored-by: Rakshitha650 <76676196+Rakshitha650@users.noreply.github.com> --- .github/workflows/postgres-init_trigger.yml | 83 ---- .github/workflows/push-trigger.yml | 96 ++++ .github/workflows/push_trigger.yml | 377 --------------- .github/workflows/release-changes.yml | 26 + .github/workflows/release_changes.yml | 61 --- .github/workflows/release_trigger.yml | 267 ----------- .github/workflows/tag.yaml | 40 +- .github/workflows/tag.yaml.orig | 75 +++ .../service/entity/CredSubjectIdStore.java | 68 +++ .../common/service/entity/PolicyData.java | 2 +- .../exception/IdAuthExceptionHandler.java | 9 + .../service/helper/AuthTransactionHelper.java | 8 +- .../service/helper/TokenValidationHelper.java | 179 +++++++ .../impl/AuthContextClazzRefProvider.java | 2 +- .../CredSubjectIdStoreRepository.java | 21 + .../repository/IdaUinHashSaltRepo.java | 1 + .../manager/IdAuthSecurityManager.java | 34 +- .../util/KeyBindedTokenMatcherUtil.java | 2 +- authentication/authentication-core/pom.xml | 388 +++++++-------- .../core/constant/AuditEvents.java | 2 + .../core/constant/AuditModules.java | 2 + .../core/constant/IdAuthCommonConstants.java | 40 ++ .../IdAuthenticationErrorConstants.java | 16 +- .../core/constant/RequestType.java | 3 +- .../core/constant/VCFormats.java | 18 + .../core/constant/VCStatus.java | 24 + .../core/indauth/dto/VCResponseDTO.java | 18 + .../VciCredentialsDefinitionRequestDTO.java | 26 + .../indauth/dto/VciExchangeRequestDTO.java | 42 ++ .../indauth/dto/VciExchangeResponseDTO.java | 19 + .../core/partner/dto/MispPolicyDTO.java | 2 + .../core/spi/indauth/facade/KycFacade.java | 4 +- .../core/spi/indauth/facade/VciFacade.java | 32 ++ .../core/spi/indauth/service/KycService.java | 3 +- .../core/spi/indauth/service/VciService.java | 47 ++ .../Dockerfile | 282 +++++------ .../InternalAuthenticationApplication.java | 310 ++++++------ .../authentication-otp-service/Dockerfile | 244 +++++----- .../otp/service/OtpApplication.java | 252 +++++----- .../authentication-service/Dockerfile | 288 ++++++------ authentication/authentication-service/pom.xml | 5 + .../service/IdAuthenticationApplication.java | 14 +- .../service/kyc/config/KycFilterConfig.java | 14 + .../IdentityWalletBindingController.java | 17 +- .../service/kyc/controller/VCIController.java | 165 +++++++ .../service/kyc/facade/KycFacadeImpl.java | 127 +---- .../service/kyc/facade/VciFacadeImpl.java | 227 +++++++++ .../service/kyc/filter/VciExchangeFilter.java | 115 +++++ .../service/kyc/impl/KycServiceImpl.java | 16 +- .../service/kyc/impl/VciServiceImpl.java | 443 ++++++++++++++++++ .../kyc/util/VCSchemaProviderUtil.java | 62 +++ .../IdentityKeyBindingRequestValidator.java | 4 +- .../KycExchangeRequestValidator.java | 5 +- .../VciExchangeRequestValidator.java | 211 +++++++++ .../esignet-integration-impl/pom.xml | 14 +- .../dto/CredentialDefinitionDTO.java | 20 + .../integration/dto/IdaVcExchangeRequest.java | 40 ++ .../dto/IdaVcExchangeResponse.java | 9 + .../helper/VCITransactionHelper.java | 30 ++ .../service/IdaAuthenticatorImpl.java | 6 +- .../service/IdaVCIssuancePluginImpl.java | 212 +++++++++ .../service/IdaAuthenticatorImplTest.java | 35 ++ authentication/pom.xml | 9 +- .../ddl/ida-cred_subject_id_store.sql | 32 ++ .../mosip_ida/dml/ida-key_policy_def.csv | 3 +- .../sql/1.2.0.1-B4_to_1.2.0.1-B5_rollback.sql | 7 + .../sql/1.2.0.1-B4_to_1.2.0.1-B5_upgrade.sql | 47 ++ 67 files changed, 3465 insertions(+), 1837 deletions(-) delete mode 100644 .github/workflows/postgres-init_trigger.yml create mode 100644 .github/workflows/push-trigger.yml delete mode 100644 .github/workflows/push_trigger.yml create mode 100644 .github/workflows/release-changes.yml delete mode 100644 .github/workflows/release_changes.yml delete mode 100644 .github/workflows/release_trigger.yml create mode 100644 .github/workflows/tag.yaml.orig create mode 100644 authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/entity/CredSubjectIdStore.java create mode 100644 authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/helper/TokenValidationHelper.java create mode 100644 authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/repository/CredSubjectIdStoreRepository.java create mode 100644 authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/VCFormats.java create mode 100644 authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/VCStatus.java create mode 100644 authentication/authentication-core/src/main/java/io/mosip/authentication/core/indauth/dto/VCResponseDTO.java create mode 100644 authentication/authentication-core/src/main/java/io/mosip/authentication/core/indauth/dto/VciCredentialsDefinitionRequestDTO.java create mode 100644 authentication/authentication-core/src/main/java/io/mosip/authentication/core/indauth/dto/VciExchangeRequestDTO.java create mode 100644 authentication/authentication-core/src/main/java/io/mosip/authentication/core/indauth/dto/VciExchangeResponseDTO.java create mode 100644 authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/facade/VciFacade.java create mode 100644 authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/service/VciService.java create mode 100644 authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/controller/VCIController.java create mode 100644 authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/facade/VciFacadeImpl.java create mode 100644 authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/filter/VciExchangeFilter.java create mode 100644 authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/impl/VciServiceImpl.java create mode 100644 authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/util/VCSchemaProviderUtil.java create mode 100644 authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/validator/VciExchangeRequestValidator.java create mode 100644 authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/dto/CredentialDefinitionDTO.java create mode 100644 authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/dto/IdaVcExchangeRequest.java create mode 100644 authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/dto/IdaVcExchangeResponse.java create mode 100644 authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/helper/VCITransactionHelper.java create mode 100644 authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/service/IdaVCIssuancePluginImpl.java create mode 100644 db_scripts/mosip_ida/ddl/ida-cred_subject_id_store.sql create mode 100644 db_upgrade_scripts/mosip_ida/sql/1.2.0.1-B4_to_1.2.0.1-B5_rollback.sql create mode 100644 db_upgrade_scripts/mosip_ida/sql/1.2.0.1-B4_to_1.2.0.1-B5_upgrade.sql diff --git a/.github/workflows/postgres-init_trigger.yml b/.github/workflows/postgres-init_trigger.yml deleted file mode 100644 index 3de4c6f32c5..00000000000 --- a/.github/workflows/postgres-init_trigger.yml +++ /dev/null @@ -1,83 +0,0 @@ -name: Trigger postgres-init repo upon db scripts updates - -on: - push: - branches: - - master - - 1.* - - develop - - release* - paths: - - db_release_scripts/** - - db_scripts/** - -jobs: - paths-filter: - runs-on: ubuntu-latest - outputs: - db_release_scripts: ${{ steps.filter.outputs.db_release_scripts }} - db_scripts: ${{ steps.filter.outputs.db_scripts }} - steps: - - uses: actions/checkout@v2 - - uses: dorny/paths-filter@v2 - id: filter - with: - base: ${{ github.ref }} - filters: | - db_release_scripts: - - 'db_release_scripts/**' - db_scripts: - - 'db_scripts/**' - - # run only if 'db_release_scripts' files were changed - db_release_scripts_updates: - needs: paths-filter - if: needs.paths-filter.outputs.db_release_scripts == 'true' - runs-on: ubuntu-latest - steps: - - name: Check for updates - run: echo "Updates are present in db_release_scripts directory, Triggering postgres-init repo" - - uses: 8398a7/action-slack@v3 - with: - status: ${{ job.status }} - fields: repo,message,commit,author,job,took,ref # selectable (default: repo,message) - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_DEVOPS }} # required - if: success() # Pick up events when the job is successful. - - # run only if not 'db_release_scripts' files were changed - - name: Check for no updates - if: needs.paths-filter.outputs.db_release_scripts != 'true' - run: echo "Updates are not present in db_release_scripts directory" - - # run only if 'db_scripts' files were changed - db_scripts_updates: - needs: paths-filter - if: needs.paths-filter.outputs.db_scripts == 'true' - runs-on: ubuntu-latest - steps: - - name: Check for updates - run: echo "Updates are present in db_scripts directory, Triggering postgres-init repo" - - uses: 8398a7/action-slack@v3 - with: - status: ${{ job.status }} - fields: repo,message,commit,author,job,took,ref # selectable (default: repo,message) - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_DEVOPS }} # required - if: success() # Pick up events when the job is successful. - - # run only if not 'db_scripts' files were changed - - name: Check for no updates - if: needs.paths-filter.outputs.db_scripts != 'true' - run: echo "Updates are not present in db_scripts directory" - - # This job is to trigger postgres-init repo. - trigger-postgres_init_repo: - runs-on: ubuntu-latest - steps: - - uses: peter-evans/repository-dispatch@v2 - with: - token: ${{ secrets.ACTION_PAT }} - repository: mosip/postgres-init - base: ${{ github.ref }} - event-type: db-event diff --git a/.github/workflows/push-trigger.yml b/.github/workflows/push-trigger.yml new file mode 100644 index 00000000000..d914a4bc0c6 --- /dev/null +++ b/.github/workflows/push-trigger.yml @@ -0,0 +1,96 @@ +name: Maven Package upon a push + +on: + release: + types: [published] + pull_request: + types: [opened] + branches: + - '!release-branch' + - release-1* + - 1.* + - develop + - MOSIP* + workflow_dispatch: + inputs: + message: + description: 'Message for manually triggering' + required: false + default: 'Triggered for Updates' + type: string + push: + branches: + - '!release-branch' + - release-1* + - master + - 1.* + - develop + +jobs: + build-maven-authentication: + uses: mosip/kattu/.github/workflows/maven-build.yml@master + with: + SERVICE_LOCATION: ./authentication + BUILD_ARTIFACT: authentication + secrets: + OSSRH_USER: ${{ secrets.OSSRH_USER }} + OSSRH_SECRET: ${{ secrets.OSSRH_SECRET }} + OSSRH_TOKEN: ${{ secrets.OSSRH_TOKEN }} + GPG_SECRET: ${{ secrets.GPG_SECRET }} + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }} + + publish_to_nexus: + if: "${{ !contains(github.ref, 'master') && github.event_name != 'pull_request' }}" + needs: build-maven-authentication + uses: mosip/kattu/.github/workflows/maven-publish-to-nexus.yml@master + with: + SERVICE_LOCATION: ./authentication + secrets: + OSSRH_USER: ${{ secrets.OSSRH_USER }} + OSSRH_SECRET: ${{ secrets.OSSRH_SECRET }} + OSSRH_URL: ${{ secrets.OSSRH_SNAPSHOT_URL }} + OSSRH_TOKEN: ${{ secrets.OSSRH_TOKEN }} + GPG_SECRET: ${{ secrets.GPG_SECRET }} + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }} + + build-dockers: + needs: build-maven-authentication + strategy: + matrix: + include: + - SERVICE_LOCATION: 'authentication/authentication-otp-service' + SERVICE_NAME: 'authentication-otp-service' + BUILD_ARTIFACT: 'authentication' + - SERVICE_LOCATION: 'authentication/authentication-internal-service' + SERVICE_NAME: 'authentication-internal-service' + BUILD_ARTIFACT: 'authentication' + - SERVICE_LOCATION: 'authentication/authentication-service' + SERVICE_NAME: 'authentication-service' + BUILD_ARTIFACT: 'authentication' + fail-fast: false + name: ${{ matrix.SERVICE_NAME }} + uses: mosip/kattu/.github/workflows/docker-build.yml@master + with: + SERVICE_LOCATION: ${{ matrix.SERVICE_LOCATION }} + SERVICE_NAME: ${{ matrix.SERVICE_NAME }} + BUILD_ARTIFACT: ${{ matrix.BUILD_ARTIFACT }} + secrets: + DEV_NAMESPACE_DOCKER_HUB: ${{ secrets.DEV_NAMESPACE_DOCKER_HUB }} + ACTOR_DOCKER_HUB: ${{ secrets.ACTOR_DOCKER_HUB }} + RELEASE_DOCKER_HUB: ${{ secrets.RELEASE_DOCKER_HUB }} + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }} + + sonar_analysis: + needs: build-maven-authentication + if: "${{ github.event_name != 'pull_request' }}" + uses: mosip/kattu/.github/workflows/maven-sonar-analysis.yml@master + with: + SERVICE_LOCATION: ./authentication + secrets: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + ORG_KEY: ${{ secrets.ORG_KEY }} + OSSRH_USER: ${{ secrets.OSSRH_USER }} + OSSRH_SECRET: ${{ secrets.OSSRH_SECRET }} + OSSRH_TOKEN: ${{ secrets.OSSRH_TOKEN }} + GPG_SECRET: ${{ secrets.GPG_SECRET }} + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }} \ No newline at end of file diff --git a/.github/workflows/push_trigger.yml b/.github/workflows/push_trigger.yml deleted file mode 100644 index 527a292428d..00000000000 --- a/.github/workflows/push_trigger.yml +++ /dev/null @@ -1,377 +0,0 @@ - -name: Maven Package upon a push - -on: - push: - branches: - - '!release-branch' - - release-1* - - master - - 1.* - - develop - -jobs: - build: - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v1 - with: - ref: ${{ github.ref }} - java-version: 11 - server-id: ossrh # Value of the distributionManagement/repository/id field of the pom.xml - settings-path: ${{ github.workspace }} # location for the settings.xml file - - - name: Setup branch and env - run: | - # Strip git ref prefix from version - echo "BRANCH_NAME=$(echo ${{ github.ref }} | sed -e 's,.*/\(.*\),\1,')" >> $GITHUB_ENV - echo "GPG_TTY=$(tty)" >> $GITHUB_ENV - - - name: Setup branch and GPG public key - run: | - # Strip git ref prefix from version - echo ${{ env.BRANCH_NAME }} - echo ${{ env.GPG_TTY }} - sudo apt-get --yes install gnupg2 - gpg2 --import ./.github/keys/mosipgpgkey_pub.gpg - gpg2 --quiet --batch --passphrase=${{secrets.gpg_secret}} --allow-secret-key-import --import ./.github/keys/mosipgpgkey_sec.gpg - - - uses: actions/cache@v1 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven-${{ env.BRANCH_NAME }} - - - name: Setup the settings file for ossrh server - run: echo " ossrh ${{secrets.ossrh_user}} ${{secrets.ossrh_secret}} ossrh true gpg2 ${{secrets.gpg_secret}} allow-snapshots true snapshots-repo https://oss.sonatype.org/content/repositories/snapshots false true releases-repo https://oss.sonatype.org/service/local/staging/deploy/maven2 true false sonar . https://sonarcloud.io false " > $GITHUB_WORKSPACE/settings.xml - - - name: Build with Maven - run: | - cd authentication - mvn -B package -s $GITHUB_WORKSPACE/settings.xml --file pom.xml -e - - - name: Ready the springboot artifacts - run: find -name '*.jar' -executable -type f -exec zip release.zip {} + - - - name: Upload the springboot jars - uses: actions/upload-artifact@v1 - with: - name: release - path: ./release.zip - - - uses: 8398a7/action-slack@v3 - with: - status: ${{ job.status }} - fields: repo,message,commit,workflow,job # selectable (default: repo,message) - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }} # required - if: failure() # Pick up events even if the job fails or is canceled. - - publish_to_nexus: - if: "!contains(github.ref, 'master')" - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v1 - with: - ref: ${{ github.ref }} - java-version: 11 - server-id: ossrh # Value of the distributionManagement/repository/id field of the pom.xml - settings-path: ${{ github.workspace }} # location for the settings.xml file - - - name: Setup branch and env - run: | - # Strip git ref prefix from version - echo "BRANCH_NAME=$(echo ${{ github.ref }} | sed -e 's,.*/\(.*\),\1,')" >> $GITHUB_ENV - echo "GPG_TTY=$(tty)" >> $GITHUB_ENV - - - name: Setup branch and GPG public key - run: | - # Strip git ref prefix from version - echo ${{ env.BRANCH_NAME }} - echo ${{ env.GPG_TTY }} - sudo apt-get --yes install gnupg2 - gpg2 --import ./.github/keys/mosipgpgkey_pub.gpg - gpg2 --quiet --batch --passphrase=${{secrets.gpg_secret}} --always-trust --allow-secret-key-import --import ./.github/keys/mosipgpgkey_sec.gpg - - - uses: actions/cache@v1 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven-${{ env.BRANCH_NAME }} - - - name: Install xmllint - run: | - sudo apt-get update - sudo apt-get install libxml2-utils - - - name: Setup the settings file for ossrh server - run: echo " ossrh ${{secrets.RELEASE_USER}} ${{secrets.RELEASE_TOKEN}} ossrh true gpg2 ${{secrets.gpg_secret}} allow-snapshots true snapshots-repo https://oss.sonatype.org/content/repositories/snapshots false true releases-repo https://oss.sonatype.org/service/local/staging/deploy/maven2 true false sonar . https://sonarcloud.io false " > $GITHUB_WORKSPACE/settings.xml - - - name: Build with Maven - run: | - cd authentication - mvn -B package -s $GITHUB_WORKSPACE/settings.xml --file pom.xml - - - name: Publish the maven package - run: | - cd authentication && mvn deploy -DaltDeploymentRepository=ossrh::default::${{ secrets.OSSRH_SNAPSHOT_URL }} -s $GITHUB_WORKSPACE/settings.xml -f pom.xml - env: - GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} - GPG_TTY: $(tty) - # - uses: 8398a7/action-slack@v3 - # with: - # status: ${{ job.status }} - # fields: repo,message,commit,workflow,job # selectable (default: repo,message) - # env: - # SLACK_WEBHOOK_URL: ${{ secrets.SLACK_DEVOPS_WEBHOOK }} # required - # if: failure() # Pick up events even if the job fails or is canceled. - - docker-authentication-otp-service: - needs: build - - runs-on: ubuntu-latest - env: - NAMESPACE: ${{ secrets.dev_namespace_docker_hub }} - SERVICE_NAME: authentication-otp-service - SERVICE_LOCATION: authentication/authentication-otp-service - - steps: - - uses: actions/checkout@v2 - - uses: actions/download-artifact@v1 - with: - name: release - path: ./ - - - name: Setup branch name - run: | - # Strip git ref prefix from version - echo "BRANCH_NAME=$(echo ${{ github.ref }} | sed -e 's,.*/\(.*\),\1,')" >> $GITHUB_ENV - - - name: Get version info from pom - id: getPomVersion - uses: mavrosxristoforos/get-xml-info@1.0 - with: - xml-file: ./${{ env.SERVICE_LOCATION }}/pom.xml - xpath: /*[local-name()="project"]/*[local-name()="version"] - - - name: Unzip and extract the authentication-otp-service - run: unzip -uj "release.zip" "${{ env.SERVICE_LOCATION }}/target/*" -d "./${{ env.SERVICE_LOCATION }}/target" - - name: Get current date - id: date - run: echo "::set-output name=date::$(date +'%Y-%m-%d')" - - - name: Build image - run: | - cd "./${{env.SERVICE_LOCATION}}" - docker build . --file Dockerfile --build-arg SOURCE=mosip --build-arg COMMIT_HASH=$(git rev-parse HEAD) --build-arg COMMIT_ID=$(git rev-parse --short HEAD) --build-arg BUILD_TIME=${{steps.date.outputs.date}} --tag ${{ env.SERVICE_NAME }} - - name: Log into registry - run: echo "${{ secrets.release_docker_hub }}" | docker login -u ${{ secrets.actor_docker_hub }} --password-stdin - - - name: Push image - run: | - IMAGE_ID=$NAMESPACE/$SERVICE_NAME - - # Change all uppercase to lowercase - IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') - echo "push version ${{steps.getPomVersion.outputs.info}}" - if [[ $BRANCH_NAME == master ]]; then - VERSION=latest - else - VERSION=$BRANCH_NAME - fi - echo IMAGE_ID=$IMAGE_ID - echo VERSION=$VERSION - docker tag $SERVICE_NAME $IMAGE_ID:$VERSION - docker push $IMAGE_ID:$VERSION - - uses: 8398a7/action-slack@v3 - with: - status: ${{ job.status }} - fields: repo,message,commit,workflow,job # selectable (default: repo,message) - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_DEVOPS_WEBHOOK }} # required - if: failure() # Pick up events even if the job fails or is canceled. - - docker-authentication-internal-service: - needs: build - - runs-on: ubuntu-latest - env: - NAMESPACE: ${{ secrets.dev_namespace_docker_hub }} - SERVICE_NAME: authentication-internal-service - SERVICE_LOCATION: authentication/authentication-internal-service - - steps: - - uses: actions/checkout@v2 - - uses: actions/download-artifact@v1 - with: - name: release - path: ./ - - - name: Setup branch name - run: | - # Strip git ref prefix from version - echo "BRANCH_NAME=$(echo ${{ github.ref }} | sed -e 's,.*/\(.*\),\1,')" >> $GITHUB_ENV - - - name: Get version info from pom - id: getPomVersion - uses: mavrosxristoforos/get-xml-info@1.0 - with: - xml-file: ./${{ env.SERVICE_LOCATION }}/pom.xml - xpath: /*[local-name()="project"]/*[local-name()="version"] - - - name: Unzip and extract the authentication-internal-service - run: unzip -uj "release.zip" "${{ env.SERVICE_LOCATION }}/target/*" -d "./${{ env.SERVICE_LOCATION }}/target" - - name: Get current date - id: date - run: echo "::set-output name=date::$(date +'%Y-%m-%d')" - - - name: Build image - run: | - cd "./${{env.SERVICE_LOCATION}}" - docker build . --file Dockerfile --build-arg SOURCE=mosip --build-arg COMMIT_HASH=$(git rev-parse HEAD) --build-arg COMMIT_ID=$(git rev-parse --short HEAD) --build-arg BUILD_TIME=${{steps.date.outputs.date}} --tag ${{ env.SERVICE_NAME }} - - name: Log into registry - run: echo "${{ secrets.release_docker_hub }}" | docker login -u ${{ secrets.actor_docker_hub }} --password-stdin - - - name: Push image - run: | - IMAGE_ID=$NAMESPACE/$SERVICE_NAME - - # Change all uppercase to lowercase - IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') - echo "push version ${{steps.getPomVersion.outputs.info}}" - if [[ $BRANCH_NAME == master ]]; then - VERSION=latest - else - VERSION=$BRANCH_NAME - fi - echo IMAGE_ID=$IMAGE_ID - echo VERSION=$VERSION - docker tag $SERVICE_NAME $IMAGE_ID:$VERSION - docker push $IMAGE_ID:$VERSION - - uses: 8398a7/action-slack@v3 - with: - status: ${{ job.status }} - fields: repo,message,commit,workflow,job # selectable (default: repo,message) - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_DEVOPS_WEBHOOK }} # required - if: failure() # Pick up events even if the job fails or is canceled. - - docker-authentication-service: - needs: build - - runs-on: ubuntu-latest - env: - NAMESPACE: ${{ secrets.dev_namespace_docker_hub }} - SERVICE_NAME: authentication-service - SERVICE_LOCATION: authentication/authentication-service - - steps: - - uses: actions/checkout@v2 - - uses: actions/download-artifact@v1 - with: - name: release - path: ./ - - - name: Setup branch name - run: | - # Strip git ref prefix from version - echo "BRANCH_NAME=$(echo ${{ github.ref }} | sed -e 's,.*/\(.*\),\1,')" >> $GITHUB_ENV - - - name: Get version info from pom - id: getPomVersion - uses: mavrosxristoforos/get-xml-info@1.0 - with: - xml-file: ./${{ env.SERVICE_LOCATION }}/pom.xml - xpath: /*[local-name()="project"]/*[local-name()="version"] - - - name: Unzip and extract the authentication-service - run: unzip -uj "release.zip" "${{ env.SERVICE_LOCATION }}/target/*" -d "./${{ env.SERVICE_LOCATION }}/target" - - name: Get current date - id: date - run: echo "::set-output name=date::$(date +'%Y-%m-%d')" - - - name: Build image - run: | - cd "./${{env.SERVICE_LOCATION}}" - docker build . --file Dockerfile --build-arg SOURCE=mosip --build-arg COMMIT_HASH=$(git rev-parse HEAD) --build-arg COMMIT_ID=$(git rev-parse --short HEAD) --build-arg BUILD_TIME=${{steps.date.outputs.date}} --tag ${{ env.SERVICE_NAME }} - - name: Log into registry - run: echo "${{ secrets.release_docker_hub }}" | docker login -u ${{ secrets.actor_docker_hub }} --password-stdin - - - name: Push image - run: | - IMAGE_ID=$NAMESPACE/$SERVICE_NAME - - # Change all uppercase to lowercase - IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') - echo "push version ${{steps.getPomVersion.outputs.info}}" - if [[ $BRANCH_NAME == master ]]; then - VERSION=latest - else - VERSION=$BRANCH_NAME - fi - echo IMAGE_ID=$IMAGE_ID - echo VERSION=$VERSION - docker tag $SERVICE_NAME $IMAGE_ID:$VERSION - docker push $IMAGE_ID:$VERSION - - uses: 8398a7/action-slack@v3 - with: - status: ${{ job.status }} - fields: repo,message,commit,workflow,job # selectable (default: repo,message) - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_DEVOPS_WEBHOOK }} # required - if: failure() # Pick up events even if the job fails or is canceled. - - sonar_analysis: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v1 - with: - ref: ${{ github.ref }} - java-version: 11 - server-id: ossrh # Value of the distributionManagement/repository/id field of the pom.xml - settings-path: ${{ github.workspace }} # location for the settings.xml file - - - name: Setup branch and env - run: | - # Strip git ref prefix from version - echo "BRANCH_NAME=$(echo ${{ github.ref }} | sed -e 's,.*/\(.*\),\1,')" >> $GITHUB_ENV - echo "GPG_TTY=$(tty)" >> $GITHUB_ENV - - - uses: actions/cache@v1 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven-${{ env.BRANCH_NAME }} - - - name: Setup the settings file for ossrh server - run: echo " ossrh ${{secrets.ossrh_user}} ${{secrets.ossrh_secret}} ossrh true gpg2 ${{secrets.gpg_secret}} allow-snapshots true snapshots-repo https://oss.sonatype.org/content/repositories/snapshots false true releases-repo https://oss.sonatype.org/service/local/staging/deploy/maven2 true false sonar . https://sonarcloud.io false " > $GITHUB_WORKSPACE/settings.xml - - - name: Build with Maven - run: | - cd authentication - mvn -B package -s $GITHUB_WORKSPACE/settings.xml --file pom.xml - - - name: Analyze with SonarCloud - run: | - cd authentication - mvn -B -Dgpg.skip verify sonar:sonar -Dsonar.projectKey=mosip_${{ github.event.repository.name }} -Dsonar.organization=${{ secrets.ORG_KEY }} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${{ secrets.SONAR_TOKEN }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN1 }} - - uses: 8398a7/action-slack@v3 - with: - status: ${{ job.status }} - fields: repo,message,commit,workflow,job # selectable (default: repo,message) - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_DEVOPS_WEBHOOK }} # required - if: failure() # Pick up events even if the job fails or is canceled. diff --git a/.github/workflows/release-changes.yml b/.github/workflows/release-changes.yml new file mode 100644 index 00000000000..2579ea836f1 --- /dev/null +++ b/.github/workflows/release-changes.yml @@ -0,0 +1,26 @@ +name: Release/pre-release Preparation. + +on: + workflow_dispatch: + inputs: + MESSAGE: + description: 'Triggered for release or pe-release' + required: false + default: 'Release Preparation' + RELEASE_TAG: + description: 'tag to update' + required: true + SNAPSHOT_TAG: + description: 'tag to be replaced' + required: true + BASE: + description: 'base branch for PR' + required: true +jobs: + maven-release-preparation: + uses: mosip/kattu/.github/workflows/release-changes.yml@master + with: + MESSAGE: ${{ inputs.MESSAGE }} + RELEASE_TAG: ${{ inputs.RELEASE_TAG }} + SNAPSHOT_TAG: ${{ inputs.SNAPSHOT_TAG }} + BASE: ${{ inputs.BASE }} \ No newline at end of file diff --git a/.github/workflows/release_changes.yml b/.github/workflows/release_changes.yml deleted file mode 100644 index 5d8e1a32989..00000000000 --- a/.github/workflows/release_changes.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Release/pre-release Preparation. - -on: - workflow_dispatch: - inputs: - message: - description: 'Triggered for release or pe-release' - required: false - default: 'Release Preparation' - releaseTags: - description: 'tag to update' - required: true - snapshotTags: - description: 'tag to be replaced' - required: true - base: - description: 'base branch for PR' - required: true -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Setup branch and env - run: | - # Strip git ref prefix from version - echo "BRANCH_NAME=$(echo ${{ github.ref }} | sed -e 's,.*/\(.*\),\1,')" >> $GITHUB_ENV - echo "GPG_TTY=$(tty)" >> $GITHUB_ENV - - - name: update Branch name in badges - run: | - sed -i 's/branch=.*)]/branch=${{ env.BRANCH_NAME }}\)]/g' README.md - sed -i 's/branch=.*\&/branch=${{ env.BRANCH_NAME }}\&/g' README.md - - - name: Mannualy changing the pom versions - run: find . -type f -name "*pom.xml" -print0 | xargs -0 sed -i "s/${{ github.event.inputs.snapshotTags }}/${{ github.event.inputs.releaseTags }}/g" - - - name: Updating the Release URL in POM - run: | - cd .github/workflows - sed -i 's/OSSRH_SNAPSHOT_URL/RELEASE_URL/g' push_trigger.yml - - - name: Updating libs-snapshot-local to libs-release local for artifactory URL's. - run: find . -type f -name "*Dockerfile" -print0 | xargs -0 sed -i "s/libs-snapshot-local/libs-release-local/g" - - - name: removing -DskipTests - run: find . -type f -name "*push_trigger.yml" -print0 | xargs -0 sed -i "s/"-DskipTests"//g" - -# - name: removing --Dgpg.skip -# run: find . -type f -name "*push_trigger.yml" -print0 | xargs -0 sed -i "s/"-Dgpg.skip"//g" - - - name: Create Pull Request - uses: peter-evans/create-pull-request@v3 - with: - token: ${{ secrets.ACTION_PAT }} - commit-message: Release Bot Pre-release changes - title: Release changes - body: Automated PR for ${{ github.event.inputs.releaseTags }} release. - branch: release-branch - delete-branch: true - base: ${{ github.event.inputs.base }} diff --git a/.github/workflows/release_trigger.yml b/.github/workflows/release_trigger.yml deleted file mode 100644 index d0f9da8d439..00000000000 --- a/.github/workflows/release_trigger.yml +++ /dev/null @@ -1,267 +0,0 @@ -name: Release maven packages and docker upon a release - -on: - release: - types: [published] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v1 - with: - ref: ${{ github.ref }} - java-version: 11 - server-id: ossrh # Value of the distributionManagement/repository/id field of the pom.xml - settings-path: ${{ github.workspace }} # location for the settings.xml file - - - name: Setup branch and GPG public key - run: | - # Strip git ref prefix from version - echo "::set-env name=BRANCH_NAME::$(echo ${{ github.ref }} | sed -e 's,.*/\(.*\),\1,')" - echo ${{ env.BRANCH_NAME }} - echo "::set-env name=GPG_TTY::$(tty)" - echo ${{ env.GPG_TTY }} - sudo apt-get --yes install gnupg2 - gpg2 --import ./.github/keys/mosipgpgkey_pub.gpg - gpg2 --quiet --batch --passphrase=${{secrets.gpg_secret}} --allow-secret-key-import --import ./.github/keys/mosipgpgkey_sec.gpg - - - uses: actions/cache@v1 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven-${{ env.BRANCH_NAME }} - - - name: Setup the settings file for ossrh server - run: echo " ossrh ${{secrets.ossrh_user}} ${{secrets.ossrh_secret}} ossrh true gpg2 ${{secrets.gpg_secret}} allow-snapshots true snapshots-repo https://oss.sonatype.org/content/repositories/snapshots false true releases-repo https://oss.sonatype.org/service/local/staging/deploy/maven2 true false sonar . https://sonarcloud.io false " > $GITHUB_WORKSPACE/settings.xml - - - - name: Build with Maven - run: | - cd authentication - mvn -B package -s $GITHUB_WORKSPACE/settings.xml --file pom.xml - - - name: Ready the springboot artifacts - run: find -name '*.jar' -executable -type f -exec zip release.zip {} + - - - name: Upload the springboot jars - uses: actions/upload-artifact@v1 - with: - name: release - path: ./release.zip - - publish_to_nexus: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v1 - with: - ref: ${{ github.ref }} - java-version: 11 - server-id: ossrh # Value of the distributionManagement/repository/id field of the pom.xml - settings-path: ${{ github.workspace }} # location for the settings.xml file - - - name: Setup branch and GPG public key - run: | - # Strip git ref prefix from version - echo "::set-env name=BRANCH_NAME::$(echo ${{ github.ref }} | sed -e 's,.*/\(.*\),\1,')" - echo ${{ env.BRANCH_NAME }} - echo "::set-env name=GPG_TTY::$(tty)" - echo ${{ env.GPG_TTY }} - sudo apt-get --yes install gnupg2 - gpg2 --import ./.github/keys/mosipgpgkey_pub.gpg - gpg2 --quiet --batch --passphrase=${{secrets.gpg_secret}} --allow-secret-key-import --import ./.github/keys/mosipgpgkey_sec.gpg - - - uses: actions/cache@v1 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven-${{ env.BRANCH_NAME }} - - - name: Install xmllint - run: | - sudo apt-get update - sudo apt-get install libxml2-utils - - - name: Setup the settings file for ossrh server - run: echo " ossrh ${{secrets.ossrh_user}} ${{secrets.ossrh_secret}} ossrh true gpg2 ${{secrets.gpg_secret}} allow-snapshots true snapshots-repo https://oss.sonatype.org/content/repositories/snapshots false true releases-repo https://oss.sonatype.org/service/local/staging/deploy/maven2 true false sonar . https://sonarcloud.io false " > $GITHUB_WORKSPACE/settings.xml - - - name: Build with Maven - run: | - cd authentication - mvn -B package -s $GITHUB_WORKSPACE/settings.xml --file pom.xml - - - name: Publish the maven package - run: | - chmod +x ./deploy.sh - ./deploy.sh authentication $GITHUB_WORKSPACE/settings.xml .* - env: - GPG_TTY: $(tty) - - name: Analyze with SonarCloud - run: | - cd authentication - mvn -B verify sonar:sonar -Dsonar.projectKey=${{ secrets.PROJECT_KEY }} -Dsonar.organization=${{ secrets.ORG_KEY }} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${{ secrets.SONAR_TOKEN }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - docker-authentication-otp-service: - needs: build - - runs-on: ubuntu-latest - env: - NAMESPACE: ${{ secrets.dev_namespace_docker_hub }} - SERVICE_NAME: authentication-otp-service - SERVICE_LOCATION: authentication/authentication-otp-service - - steps: - - uses: actions/checkout@v2 - - uses: actions/download-artifact@v1 - with: - name: release - path: ./ - - - name: Setup branch name - run: | - # Strip git ref prefix from version - echo "::set-env name=BRANCH_NAME::$(echo ${{ github.ref }} | sed -e 's,.*/\(.*\),\1,')" - echo ${{ env.BRANCH_NAME }} - - - name: Get version info from pom - id: getPomVersion - uses: mavrosxristoforos/get-xml-info@1.0 - with: - xml-file: ./${{ env.SERVICE_LOCATION }}/pom.xml - xpath: /*[local-name()="project"]/*[local-name()="version"] - - - name: Unzip and extract the authentication-otp-service - run: unzip -uj "release.zip" "${{ env.SERVICE_LOCATION }}/target/*" -d "./${{ env.SERVICE_LOCATION }}/target" - - - name: Build image - run: | - cd "./${{env.SERVICE_LOCATION}}" - docker build . --file Dockerfile --tag ${{ env.SERVICE_NAME }} - - name: Log into registry - run: echo "${{ secrets.release_docker_hub }}" | docker login -u ${{ secrets.actor_docker_hub }} --password-stdin - - - name: Push image - run: | - IMAGE_ID=$NAMESPACE/$SERVICE_NAME - - # Change all uppercase to lowercase - IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') - echo "push version ${{steps.getPomVersion.outputs.info}}" - VERSION=$BRANCH_NAME - echo IMAGE_ID=$IMAGE_ID - echo VERSION=$VERSION - docker tag $SERVICE_NAME $IMAGE_ID:$VERSION - docker push $IMAGE_ID:$VERSION - docker-authentication-internal-service: - needs: build - - runs-on: ubuntu-latest - env: - NAMESPACE: ${{ secrets.dev_namespace_docker_hub }} - SERVICE_NAME: authentication-internal-service - SERVICE_LOCATION: authentication/authentication-internal-service - - steps: - - uses: actions/checkout@v2 - - uses: actions/download-artifact@v1 - with: - name: release - path: ./ - - - name: Setup branch name - run: | - # Strip git ref prefix from version - echo "::set-env name=BRANCH_NAME::$(echo ${{ github.ref }} | sed -e 's,.*/\(.*\),\1,')" - echo ${{ env.BRANCH_NAME }} - - - name: Get version info from pom - id: getPomVersion - uses: mavrosxristoforos/get-xml-info@1.0 - with: - xml-file: ./${{ env.SERVICE_LOCATION }}/pom.xml - xpath: /*[local-name()="project"]/*[local-name()="version"] - - - name: Unzip and extract the authentication-internal-service - run: unzip -uj "release.zip" "${{ env.SERVICE_LOCATION }}/target/*" -d "./${{ env.SERVICE_LOCATION }}/target" - - - name: Build image - run: | - cd "./${{env.SERVICE_LOCATION}}" - docker build . --file Dockerfile --tag ${{ env.SERVICE_NAME }} - - name: Log into registry - run: echo "${{ secrets.release_docker_hub }}" | docker login -u ${{ secrets.actor_docker_hub }} --password-stdin - - - name: Push image - run: | - IMAGE_ID=$NAMESPACE/$SERVICE_NAME - - # Change all uppercase to lowercase - IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') - echo "push version ${{steps.getPomVersion.outputs.info}}" - VERSION=$BRANCH_NAME - echo IMAGE_ID=$IMAGE_ID - echo VERSION=$VERSION - docker tag $SERVICE_NAME $IMAGE_ID:$VERSION - docker push $IMAGE_ID:$VERSION - docker-authentication-service: - needs: build - - runs-on: ubuntu-latest - env: - NAMESPACE: ${{ secrets.dev_namespace_docker_hub }} - SERVICE_NAME: authentication-service - SERVICE_LOCATION: authentication/authentication-service - - steps: - - uses: actions/checkout@v2 - - uses: actions/download-artifact@v1 - with: - name: release - path: ./ - - - name: Setup branch name - run: | - # Strip git ref prefix from version - echo "::set-env name=BRANCH_NAME::$(echo ${{ github.ref }} | sed -e 's,.*/\(.*\),\1,')" - echo ${{ env.BRANCH_NAME }} - - - name: Get version info from pom - id: getPomVersion - uses: mavrosxristoforos/get-xml-info@1.0 - with: - xml-file: ./${{ env.SERVICE_LOCATION }}/pom.xml - xpath: /*[local-name()="project"]/*[local-name()="version"] - - - name: Unzip and extract the authentication-service - run: unzip -uj "release.zip" "${{ env.SERVICE_LOCATION }}/target/*" -d "./${{ env.SERVICE_LOCATION }}/target" - - - name: Build image - run: | - cd "./${{env.SERVICE_LOCATION}}" - docker build . --file Dockerfile --tag ${{ env.SERVICE_NAME }} - - name: Log into registry - run: echo "${{ secrets.release_docker_hub }}" | docker login -u ${{ secrets.actor_docker_hub }} --password-stdin - - - name: Push image - run: | - IMAGE_ID=$NAMESPACE/$SERVICE_NAME - - # Change all uppercase to lowercase - IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') - echo "push version ${{steps.getPomVersion.outputs.info}}" - VERSION=$BRANCH_NAME - echo IMAGE_ID=$IMAGE_ID - echo VERSION=$VERSION - docker tag $SERVICE_NAME $IMAGE_ID:$VERSION - docker push $IMAGE_ID:$VERSION diff --git a/.github/workflows/tag.yaml b/.github/workflows/tag.yaml index e9bba0e65a0..73c55b03d8f 100644 --- a/.github/workflows/tag.yaml +++ b/.github/workflows/tag.yaml @@ -1,43 +1,33 @@ name: Tagging of repos -env: - tag: v1.2.3 - on: workflow_dispatch: inputs: - tag: + TAG: description: 'Tag to be published' required: true - default: 'v1.2.3' type: string - body: + BODY: description: 'Release body message' required: true default: 'Changes in this Release' type: string - pre-release: + PRE_RELEASE: description: 'Pre-release? True/False' required: true default: False type: string + DRAFT: + description: 'Draft? True/False' + required: false + default: False + type: string jobs: - build: - name: Create Release - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v2 - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token - with: - tag_name: ${{ github.event.inputs.tag }} - release_name: ${{ github.event.inputs.tag }} - body: | - ${{ github.event.inputs.body }} - draft: false - prerelease: ${{fromJSON(github.event.inputs.pre-release)}} + tag-branch: + uses: mosip/kattu/.github/workflows/tag.yml@master + with: + TAG: ${{ inputs.TAG }} + BODY: ${{ inputs.BODY }} + PRE_RELEASE: ${{ inputs.PRE_RELEASE }} + DRAFT: ${{ inputs.DRAFT }} \ No newline at end of file diff --git a/.github/workflows/tag.yaml.orig b/.github/workflows/tag.yaml.orig new file mode 100644 index 00000000000..b0e5bdff4e0 --- /dev/null +++ b/.github/workflows/tag.yaml.orig @@ -0,0 +1,75 @@ +name: Tagging of repos + +<<<<<<< HEAD +on: + workflow_dispatch: + inputs: + TAG: + description: 'Tag to be published' + required: true + type: string + BODY: +======= +env: + tag: v1.2.3 + +on: + workflow_dispatch: + inputs: + tag: + description: 'Tag to be published' + required: true + default: 'v1.2.3' + type: string + body: +>>>>>>> 81681ea2e2 ([MOSIP-20028] added action for tagging) + description: 'Release body message' + required: true + default: 'Changes in this Release' + type: string +<<<<<<< HEAD + PRE_RELEASE: +======= + pre-release: +>>>>>>> 81681ea2e2 ([MOSIP-20028] added action for tagging) + description: 'Pre-release? True/False' + required: true + default: False + type: string +<<<<<<< HEAD + DRAFT: + description: 'Draft? True/False' + required: false + default: False + type: string + +jobs: + tag-branch: + uses: mosip/kattu/.github/workflows/tag.yml@master + with: + TAG: ${{ inputs.TAG }} + BODY: ${{ inputs.BODY }} + PRE_RELEASE: ${{ inputs.PRE_RELEASE }} + DRAFT: ${{ inputs.DRAFT }} +======= + +jobs: + build: + name: Create Release + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + with: + tag_name: ${{ github.event.inputs.tag }} + release_name: ${{ github.event.inputs.tag }} + body: | + ${{ github.event.inputs.body }} + draft: false + prerelease: ${{fromJSON(github.event.inputs.pre-release)}} +>>>>>>> 81681ea2e2 ([MOSIP-20028] added action for tagging) diff --git a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/entity/CredSubjectIdStore.java b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/entity/CredSubjectIdStore.java new file mode 100644 index 00000000000..d0a8a9eab82 --- /dev/null +++ b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/entity/CredSubjectIdStore.java @@ -0,0 +1,68 @@ +package io.mosip.authentication.common.service.entity; + +import java.time.LocalDateTime; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.validation.constraints.NotNull; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Data +@Table(name = "cred_subject_id_store", schema = "ida") +@Entity +public class CredSubjectIdStore { + + @Id + @NotNull + @Column(name = "id") + private String id; + + @NotNull + @Column(name = "id_vid_hash") + private String idVidHash; + + @NotNull + @Column(name = "token_id") + private String tokenId; + + @NotNull + @Column(name = "cred_subject_id") + private String credSubjectId; + + @NotNull + @Column(name = "csid_key_hash") + private String csidKeyHash; + + @NotNull + @Column(name = "oidc_client_id") + private String oidcClientId; + + @NotNull + @Column(name = "csid_status") + private String csidStatus; + + @NotNull + @Column(name = "cr_by") + private String createdBy; + + @NotNull + @Column(name = "cr_dtimes") + private LocalDateTime crDTimes; + + @Column(name = "upd_by") + private String updatedBy; + + @Column(name = "upd_dtimes") + private LocalDateTime updDTimes; + + @Column(name = "is_deleted") + private boolean isDeleted; + + @Column(name = "del_dtimes") + private LocalDateTime delDTimes; +} diff --git a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/entity/PolicyData.java b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/entity/PolicyData.java index 5898b958ecb..358b121a066 100644 --- a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/entity/PolicyData.java +++ b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/entity/PolicyData.java @@ -97,7 +97,7 @@ public JSONObject getPolicy() { return OBJECT_MAPPER.readValue(CryptoUtil.decodeBase64Url(new String(this.policy)), JSONObject.class); } catch (IOException e) { // This block will never be executed - e.printStackTrace(); + //e.printStackTrace(); return null; } } diff --git a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/exception/IdAuthExceptionHandler.java b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/exception/IdAuthExceptionHandler.java index c98bd7d787e..6a01b5a226a 100644 --- a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/exception/IdAuthExceptionHandler.java +++ b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/exception/IdAuthExceptionHandler.java @@ -46,6 +46,8 @@ import io.mosip.authentication.core.indauth.dto.EncryptedKycRespDTO; import io.mosip.authentication.core.indauth.dto.KycExchangeResponseDTO; import io.mosip.authentication.core.indauth.dto.ResponseDTO; +import io.mosip.authentication.core.indauth.dto.VCResponseDTO; +import io.mosip.authentication.core.indauth.dto.VciExchangeResponseDTO; import io.mosip.authentication.core.logger.IdaLogger; import io.mosip.authentication.core.otp.dto.OtpResponseDTO; import io.mosip.idrepository.core.exception.RestServiceException; @@ -382,6 +384,13 @@ private static Object frameErrorResponse(String requestReceived, String type, Li EncryptedKycRespDTO encryptedKycRespDTO = new EncryptedKycRespDTO(); kycExchangeResponseDTO.setResponse(encryptedKycRespDTO); return kycExchangeResponseDTO; + case "vci-exchange": + VciExchangeResponseDTO vciExchangeResponseDTO = new VciExchangeResponseDTO(); + vciExchangeResponseDTO.setErrors(errors); + vciExchangeResponseDTO.setResponseTime(responseTime); + VCResponseDTO vcResponseDTO = null; + vciExchangeResponseDTO.setResponse(vcResponseDTO); + return vciExchangeResponseDTO; case "internal": if (Objects.nonNull(type) && type.equalsIgnoreCase(IdAuthCommonConstants.OTP)) { OtpResponseDTO internalotpresponsedto = new OtpResponseDTO(); diff --git a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/helper/AuthTransactionHelper.java b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/helper/AuthTransactionHelper.java index e5572cd6ee2..99e2b2675ba 100644 --- a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/helper/AuthTransactionHelper.java +++ b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/helper/AuthTransactionHelper.java @@ -36,6 +36,7 @@ import io.mosip.authentication.core.indauth.dto.IdType; import io.mosip.authentication.core.indauth.dto.IdentityKeyBindingRequestDTO; import io.mosip.authentication.core.indauth.dto.KycExchangeRequestDTO; +import io.mosip.authentication.core.indauth.dto.VciExchangeRequestDTO; import io.mosip.authentication.core.logger.IdaLogger; import io.mosip.authentication.core.otp.dto.OtpRequestDTO; import io.mosip.authentication.core.partner.dto.PartnerDTO; @@ -268,7 +269,12 @@ private AuthTransactionBuilder createAuthTxnBuilder(ObjectWithMetadata requestDT IdentityKeyBindingRequestDTO keyBindingRequestDTO = (IdentityKeyBindingRequestDTO) requestDTO; authTransactionBuilder.withRequest(keyBindingRequestDTO); authTransactionBuilder.addRequestType(RequestType.IDENTITY_KEY_BINDING); - } + } else if(requestDTO instanceof VciExchangeRequestDTO) { + VciExchangeRequestDTO vciExchangeRequestDTO = (VciExchangeRequestDTO) requestDTO; + authTransactionBuilder.withRequest(vciExchangeRequestDTO); + authTransactionBuilder.addRequestType(RequestType.VCI_EXCHANGE_REQUEST); + } + return authTransactionBuilder; } diff --git a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/helper/TokenValidationHelper.java b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/helper/TokenValidationHelper.java new file mode 100644 index 00000000000..b3a56eba064 --- /dev/null +++ b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/helper/TokenValidationHelper.java @@ -0,0 +1,179 @@ +package io.mosip.authentication.common.service.helper; + +import java.time.LocalDateTime; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; + +import io.mosip.authentication.common.service.entity.KycTokenData; +import io.mosip.authentication.common.service.entity.OIDCClientData; +import io.mosip.authentication.common.service.repository.KycTokenDataRepository; +import io.mosip.authentication.common.service.repository.OIDCClientDataRepository; +import io.mosip.authentication.common.service.util.EnvUtil; +import io.mosip.authentication.common.service.util.IdaRequestResponsConsumerUtil; +import io.mosip.authentication.core.constant.IdAuthCommonConstants; +import io.mosip.authentication.core.constant.IdAuthenticationErrorConstants; +import io.mosip.authentication.core.constant.KycTokenStatusType; +import io.mosip.authentication.core.exception.IdAuthenticationBusinessException; +import io.mosip.authentication.core.indauth.dto.BaseRequestDTO; +import io.mosip.authentication.core.logger.IdaLogger; +import io.mosip.authentication.core.spi.indauth.service.KycService; +import io.mosip.kernel.core.logger.spi.Logger; + +/** + * Helper class to Validate Token returned in kyc-auth. + * + * @author Mahammed Taheer + */ + +public class TokenValidationHelper { + + /** The mosip logger. */ + private static Logger mosipLogger = IdaLogger.getLogger(TokenValidationHelper.class); + + @Value("${ida.idp.consented.individual_id.attribute.name:individual_id}") + private String consentedIndividualIdAttributeName; + + + /** The Kyc Service */ + @Autowired + private KycService kycService; + + @Autowired + private KycTokenDataRepository kycTokenDataRepo; + + @Autowired + private IdInfoHelper idInfoHelper; + + @Autowired + private OIDCClientDataRepository oidcClientDataRepo; + + + public KycTokenData findAndValidateIssuedToken(String tokenData, String oidcClientId, String reqTransactionId, + String idvidHash) throws IdAuthenticationBusinessException { + + mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "findAndValidateIssuedToken", + "Check Token Exists or not, associated with oidc client and active status."); + + Optional tokenDataOpt = kycTokenDataRepo.findByKycToken(tokenData); + if (!tokenDataOpt.isPresent()) { + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "findAndValidateIssuedToken", + "KYC Token not found: " + tokenData); + throw new IdAuthenticationBusinessException( + IdAuthenticationErrorConstants.KYC_TOKEN_NOT_FOUND.getErrorCode(), + IdAuthenticationErrorConstants.KYC_TOKEN_NOT_FOUND.getErrorMessage()); + } + KycTokenData tokenDataObj = tokenDataOpt.get(); + validateToken(tokenDataObj, oidcClientId, reqTransactionId, idvidHash); + return tokenDataObj; + } + + private void validateToken(KycTokenData kycTokenData, String oidcClientId, String reqTransactionId, String idvidHash) + throws IdAuthenticationBusinessException { + String kycToken = kycTokenData.getKycToken(); + if (kycTokenData.getKycTokenStatus().equals(KycTokenStatusType.PROCESSED.getStatus())) { + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "findAndValidateIssuedToken", + "KYC Token already processed: " + kycToken); + throw new IdAuthenticationBusinessException( + IdAuthenticationErrorConstants.KYC_TOKEN_ALREADY_PROCESSED.getErrorCode(), + IdAuthenticationErrorConstants.KYC_TOKEN_ALREADY_PROCESSED.getErrorMessage()); + } + + if (kycTokenData.getKycTokenStatus().equals(KycTokenStatusType.EXPIRED.getStatus())) { + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "findAndValidateIssuedToken", + "KYC Token expired: " + kycToken); + throw new IdAuthenticationBusinessException( + IdAuthenticationErrorConstants.KYC_TOKEN_EXPIRED.getErrorCode(), + IdAuthenticationErrorConstants.KYC_TOKEN_EXPIRED.getErrorMessage()); + } + + if (!kycTokenData.getOidcClientId().equals(oidcClientId)) { + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "findAndValidateIssuedToken", + "KYC Token does not belongs to the provided OIDC Client Id: " + kycToken); + throw new IdAuthenticationBusinessException( + IdAuthenticationErrorConstants.KYC_TOKEN_INVALID_OIDC_CLIENT_ID.getErrorCode(), + IdAuthenticationErrorConstants.KYC_TOKEN_INVALID_OIDC_CLIENT_ID.getErrorMessage()); + } + + if (!kycTokenData.getIdVidHash().equals(idvidHash)) { + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "findAndValidateIssuedToken", + "KYC Token does not belongs to the provided UIN/VID: " + kycToken); + throw new IdAuthenticationBusinessException( + IdAuthenticationErrorConstants.KYC_TOKEN_INVALID_UIN_VID.getErrorCode(), + IdAuthenticationErrorConstants.KYC_TOKEN_INVALID_UIN_VID.getErrorMessage()); + } + + if (!kycTokenData.getRequestTransactionId().equals(reqTransactionId)) { + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "findAndValidateIssuedToken", + "KYC Auth & KYC Exchange Transaction Ids are not same: " + kycToken); + throw new IdAuthenticationBusinessException( + IdAuthenticationErrorConstants.KYC_TOKEN_INVALID_TRANSACTION_ID.getErrorCode(), + IdAuthenticationErrorConstants.KYC_TOKEN_INVALID_TRANSACTION_ID.getErrorMessage()); + } + + mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "findAndValidateIssuedToken", + "KYC Token found, Check Token expire."); + LocalDateTime tokenIssuedDateTime = kycTokenData.getTokenIssuedDateTime(); + boolean isExpired = kycService.isKycTokenExpire(tokenIssuedDateTime, kycToken); + + if (isExpired) { + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "findAndValidateIssuedToken", + "KYC Token expired."); + kycTokenData.setKycTokenStatus(KycTokenStatusType.EXPIRED.getStatus()); + kycTokenDataRepo.saveAndFlush(kycTokenData); + throw new IdAuthenticationBusinessException( + IdAuthenticationErrorConstants.KYC_TOKEN_EXPIRED.getErrorCode(), + IdAuthenticationErrorConstants.KYC_TOKEN_EXPIRED.getErrorMessage()); + } + } + + public void mapConsentedAttributesToIdSchemaAttributes(List consentAttributes, Set filterAttributes, + List policyAllowedKycAttribs) throws IdAuthenticationBusinessException { + + if(consentAttributes != null && !consentAttributes.isEmpty()) { + for (String attrib : consentAttributes) { + Collection idSchemaAttribute = idInfoHelper.getIdentityAttributesForIdName(attrib); + filterAttributes.addAll(idSchemaAttribute); + } + // removing individual id from consent if the claim is not allowed in policy. + if (!policyAllowedKycAttribs.contains(consentedIndividualIdAttributeName)) { + consentAttributes.remove(consentedIndividualIdAttributeName); + } + } + } + + public Set filterByPolicyAllowedAttributes(Set filterAttributes, List policyAllowedKycAttribs) { + return policyAllowedKycAttribs.stream() + .filter(attribute -> filterAttributes.contains(attribute)) + .collect(Collectors.toSet()); + } + + public String getKycExchangeResponseTime(BaseRequestDTO authRequestDTO) { + String dateTimePattern = EnvUtil.getDateTimePattern(); + return IdaRequestResponsConsumerUtil.getResponseTime(authRequestDTO.getRequestTime(), dateTimePattern); + } + + public List filterAllowedUserClaims(String oidcClientId, List consentAttributes) { + mosipLogger.info(IdAuthCommonConstants.IDA, this.getClass().getSimpleName(), "filterAllowedUserClaims", + "Checking for OIDC client allowed userclaims"); + Optional oidcClientData = oidcClientDataRepo.findByClientId(oidcClientId); + + List oidcClientAllowedUserClaims = List.of(oidcClientData.get().getUserClaims()) + .stream() + .map(String::toLowerCase) + .collect(Collectors.toList()); + if (consentAttributes.isEmpty()) { + return oidcClientAllowedUserClaims; + } + + return consentAttributes.stream() + .filter(claim -> oidcClientAllowedUserClaims.contains(claim.toLowerCase())) + .collect(Collectors.toList()); + + } +} diff --git a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/impl/AuthContextClazzRefProvider.java b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/impl/AuthContextClazzRefProvider.java index d7927ba0b3a..dde443ae234 100644 --- a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/impl/AuthContextClazzRefProvider.java +++ b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/impl/AuthContextClazzRefProvider.java @@ -80,7 +80,7 @@ private AuthMethodsRefValues createAuthMethodsRefValuesObject() throws IdAuthent logger.error(IdAuthCommonConstants.IDA, this.getClass().getSimpleName(), "createAuthMethodsRefValuesObject", "Not able to download the AMR-ACR Json config file. URI: " + amracrMappingUri, e); throw new IdAuthenticationBusinessException(IdAuthenticationErrorConstants.DOWNLOAD_ERROR.getErrorCode(), - IdAuthenticationErrorConstants.DOWNLOAD_ERROR.getErrorMessage()); + IdAuthenticationErrorConstants.DOWNLOAD_ERROR.getErrorMessage()); } /* ClientResponse clientResponse = webClient.get().uri(amracrMappingUri).accept(MediaType.APPLICATION_JSON).exchange().block(); diff --git a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/repository/CredSubjectIdStoreRepository.java b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/repository/CredSubjectIdStoreRepository.java new file mode 100644 index 00000000000..31551916059 --- /dev/null +++ b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/repository/CredSubjectIdStoreRepository.java @@ -0,0 +1,21 @@ +package io.mosip.authentication.common.service.repository; + +import java.util.List; + + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import io.mosip.authentication.common.service.entity.CredSubjectIdStore; + +/** + * The Interface CredSubjectIdStoreRepository. + * + * @author Mahammed Taheer + */ + +@Repository +public interface CredSubjectIdStoreRepository extends JpaRepository { + + List findAllByCsidKeyHash(String keyHash); +} diff --git a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/repository/IdaUinHashSaltRepo.java b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/repository/IdaUinHashSaltRepo.java index 8403f262f83..360d086e4d8 100644 --- a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/repository/IdaUinHashSaltRepo.java +++ b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/repository/IdaUinHashSaltRepo.java @@ -23,6 +23,7 @@ public interface IdaUinHashSaltRepo extends JpaRepository generateKeyBindingCertificate(PublicKey publicKey, CertificateParameters certParams) throws CertificateEncodingException { @@ -673,4 +694,15 @@ public Entry generateKeyBindingCertificate(PublicKey publicKey, return new SimpleEntry<>(certThumbprint, certificateData); } + + @WithRetry + public String jwtEncrypt(String dataToEncrypt, String certificateData) { + JWTEncryptRequestDto encryptRequestDto = new JWTEncryptRequestDto(); + encryptRequestDto.setData(CryptoUtil.encodeBase64Url(dataToEncrypt.getBytes())); + encryptRequestDto.setX509Certificate(certificateData); + encryptRequestDto.setEnableDefCompression(true); + encryptRequestDto.setIncludeCertHash(true); + JWTCipherResponseDto cipherResponseDto = cryptomanagerService.jwtEncrypt(encryptRequestDto); + return cipherResponseDto.getData(); + } } diff --git a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/util/KeyBindedTokenMatcherUtil.java b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/util/KeyBindedTokenMatcherUtil.java index 88629e1d311..cf3ff8f905c 100644 --- a/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/util/KeyBindedTokenMatcherUtil.java +++ b/authentication/authentication-common/src/main/java/io/mosip/authentication/common/service/util/KeyBindedTokenMatcherUtil.java @@ -169,7 +169,7 @@ private boolean isIatWithinAllowedTime(Date issuedDateTime) { LocalDateTime issuedLDT = DateUtils.parseDateToLocalDateTime(issuedDateTime); long diffSeconds = ChronoUnit.SECONDS.between(issuedLDT, currentTime); - if (issuedDateTime != null && diffSeconds > 0 && diffSeconds <= iatAdjSeconds) { + if (issuedDateTime != null && diffSeconds >= 0 && diffSeconds <= iatAdjSeconds) { return true; } return false; diff --git a/authentication/authentication-core/pom.xml b/authentication/authentication-core/pom.xml index 33cffea81e5..a3a3b1fa7b9 100644 --- a/authentication/authentication-core/pom.xml +++ b/authentication/authentication-core/pom.xml @@ -1,194 +1,194 @@ - - 4.0.0 - - - io.mosip.authentication - authentication-parent - 1.2.0.1-B5-SNAPSHOT - - 1.2.0.1-B5-SNAPSHOT - - authentication-core - jar - - authentication-core - Maven project of MOSIP ID-Authentication Core - - - - - io.mosip.kernel - kernel-core - ${kernel-core.version} - - - org.springframework.boot - - spring-boot-starter-security - - - - com.fasterxml.jackson.core - jackson-databind - - - - - - - - commons-codec - commons-codec - ${commons.codec.version} - - - org.apache.commons - commons-lang3 - ${commons.lang.version} - - - - org.springframework.boot - spring-boot-starter-web - ${spring.boot.version} - - - com.fasterxml.jackson.core - jackson-databind - - - - - org.springframework.boot - spring-boot-starter-cache - ${spring.boot.version} - - - - - com.machinezoo.sourceafis - sourceafis - ${sourceafis.version} - - - com.fasterxml.jackson.core - jackson-databind - - - - - - io.mosip.idrepository - id-repository-core - ${id-repository-core.version} - - - io.mosip.kernel - kernel-auth-adapter - - - org.springframework.boot - - spring-boot-starter-security - - - - org.springframework.security - spring-security-test - - - - - io.mosip.kernel - kernel-biosdk-provider - ${kernel-biosdk-provider.version} - - - io.mosip.kernel - kernel-core - - - io.mosip.kernel - kernel-biometrics-api - - - - - io.mosip.kernel - kernel-demographics-api - ${kernel-demoapi.version} - - - com.fasterxml.jackson.core - jackson-databind - - - - - org.springframework.boot - spring-boot-starter-webflux - ${spring.boot.version} - - - com.fasterxml.jackson.core - jackson-databind - - - - - org.springdoc - springdoc-openapi-ui - ${springdoc.version} - - - com.fasterxml.jackson.core - jackson-databind - - - - - io.mosip.kernel - kernel-logger-logback - ${kernel-logger-logback.version} - - - org.springframework.boot - - spring-boot-starter-security - - - - com.fasterxml.jackson.core - jackson-databind - - - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - - - com.fasterxml.jackson.module - jackson-module-afterburner - ${jackson.version} - - - io.mosip.kernel - kernel-biometrics-api - ${kernel-biometrics-api.version} - - - io.mosip.kernel - kernel-core - - - com.fasterxml.jackson.core - jackson-databind - - - - - + + 4.0.0 + + + io.mosip.authentication + authentication-parent + 1.2.0.1-B5-SNAPSHOT + + 1.2.0.1-B5-SNAPSHOT + + authentication-core + jar + + authentication-core + Maven project of MOSIP ID-Authentication Core + + + + + io.mosip.kernel + kernel-core + ${kernel-core.version} + + + org.springframework.boot + + spring-boot-starter-security + + + + com.fasterxml.jackson.core + jackson-databind + + + + + + + + commons-codec + commons-codec + ${commons.codec.version} + + + org.apache.commons + commons-lang3 + ${commons.lang.version} + + + + org.springframework.boot + spring-boot-starter-web + ${spring.boot.version} + + + com.fasterxml.jackson.core + jackson-databind + + + + + org.springframework.boot + spring-boot-starter-cache + ${spring.boot.version} + + + + + com.machinezoo.sourceafis + sourceafis + ${sourceafis.version} + + + com.fasterxml.jackson.core + jackson-databind + + + + + + io.mosip.idrepository + id-repository-core + ${id-repository-core.version} + + + io.mosip.kernel + kernel-auth-adapter + + + org.springframework.boot + + spring-boot-starter-security + + + + org.springframework.security + spring-security-test + + + + + io.mosip.kernel + kernel-biosdk-provider + ${kernel-biosdk-provider.version} + + + io.mosip.kernel + kernel-core + + + io.mosip.kernel + kernel-biometrics-api + + + + + io.mosip.kernel + kernel-demographics-api + ${kernel-demoapi.version} + + + com.fasterxml.jackson.core + jackson-databind + + + + + org.springframework.boot + spring-boot-starter-webflux + ${spring.boot.version} + + + com.fasterxml.jackson.core + jackson-databind + + + + + org.springdoc + springdoc-openapi-ui + ${springdoc.version} + + + com.fasterxml.jackson.core + jackson-databind + + + + + io.mosip.kernel + kernel-logger-logback + ${kernel-logger-logback.version} + + + org.springframework.boot + + spring-boot-starter-security + + + + com.fasterxml.jackson.core + jackson-databind + + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + com.fasterxml.jackson.module + jackson-module-afterburner + ${jackson.version} + + + io.mosip.kernel + kernel-biometrics-api + ${kernel-biometrics-api.version} + + + io.mosip.kernel + kernel-core + + + com.fasterxml.jackson.core + jackson-databind + + + + + diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/AuditEvents.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/AuditEvents.java index eddf713814a..f46389d51a8 100644 --- a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/AuditEvents.java +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/AuditEvents.java @@ -46,6 +46,8 @@ public enum AuditEvents { KYC_EXCHANGE_REQUEST_RESPONSE("IDA_015", "System", "Kyc Exchange Request"), KEY_BINDIN_REQUEST_RESPONSE("IDA_016", "System", "Identity Key Binding Request"), + + VCI_EXCHANGE_REQUEST_RESPONSE("IDA_017", "System", "Vci Exchange Request"), /** Static_Pin_Storage_Request_Response. */ STATIC_PIN_STORAGE_REQUEST_RESPONSE("IDA-EVT-OLD-006","BUSINESS", ""),//not applicable for release v1 diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/AuditModules.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/AuditModules.java index b49641d2eb9..f6419cbd278 100644 --- a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/AuditModules.java +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/AuditModules.java @@ -31,6 +31,8 @@ public enum AuditModules { KYC_EXCHANGE("IDA-KEX", "KYC Exchange Request", "KYC Exchange"), + VCI_EXCHANGE("IDA-VCI", "VCI Exchange Request", "VCI Exchange"), + IDENTITY_KEY_BINDING("IDA-IKB", "Identity Key Binding Request", "Key Binding"), /** The otp request. */ diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthCommonConstants.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthCommonConstants.java index ab3cf18d428..bb6a7cfda95 100644 --- a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthCommonConstants.java +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthCommonConstants.java @@ -403,6 +403,46 @@ public final class IdAuthCommonConstants { public static final String CERT_TP_AF_SEPERATOR = "-"; + public static final String CREDENTIAL_SUBJECT_ID = "credSubjectId"; + + public static final String VC_FORMAT = "vcFormat"; + + public static final String VC_AUTH_TOKEN = "vcAuthToken"; + + public static final String VC_CREDENTIAL_TYPE = "credentialType"; + + public static final boolean VCI_EXCHANGE_CONSUME_VID_DEFAULT = true; + + public static final Character COLON = ':'; + + public static final String JWK_KEY_TYPE = "kty"; + + public static final String VC_ID = "id"; + + public static final String LANGUAGE_STRING = "language"; + + public static final String VALUE_STRING = "value"; + + public static final String VC_AT_CONTEXT = "@context"; + + public static final String VC_TYPE = "type"; + + public static final String VC_ISSUER = "issuer"; + + public static final String VC_ISSUANCE_DATE = "issuanceDate"; + + public static final String VC_PROOF_CREATED = "created"; + + public static final String VC_PROOF_PURPOSE = "proofPurpose"; + + public static final String VC_PROOF_TYPE = "type"; + + public static final String VC_PROOF_VERIFICATION_METHOD = "verificationMethod"; + + public static final String CREDENTIALSUBJECT = "credentialSubject"; + + public static final String VCI_EXCHANGE_SUCCESS = "VciExchange status : true"; + private IdAuthCommonConstants() { } } diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthenticationErrorConstants.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthenticationErrorConstants.java index ace98f21e97..eefa8d8ca90 100644 --- a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthenticationErrorConstants.java +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/IdAuthenticationErrorConstants.java @@ -144,6 +144,9 @@ public enum IdAuthenticationErrorConstants { "Please bind a key for the input VID/UIN before performing KBT Auth."), KEY_BINDING_CHECK_FAILED("IDA-MPA-035", "KeyBindedToken check failed for the given token.", "Provide Valid KeyBindedToken to perform auth."), + UNAUTHORISED_VCI_EXCHANGE_PARTNER("IDA-MPA-036", "Partner is unauthorised for VCI-Exchange"), + VCI_EXCHANGE_NOT_ALLOWED("IDA-MPA-037", "%s not allowed as per policy", + "Please try after updating misp policy"), DATA_VALIDATION_FAILED("IDA-IDV-001", "Input Data Validation Failed"), @@ -192,14 +195,23 @@ public enum IdAuthenticationErrorConstants { KYC_TOKEN_ALREADY_PROCESSED("IDA-KYE-003", "KYC Token already processed."), KYC_TOKEN_INVALID_OIDC_CLIENT_ID("IDA-KYE-004", "KYC Token does not belong to the input oidc client id."), KYC_TOKEN_INVALID_TRANSACTION_ID("IDA-KYE-005", "KYC Auth and KYC Exchange transaction ids are different."), - PARTNER_POLICY_NOT_FOUND("IDA-KYE-004", "Partner Policy not found."), + PARTNER_POLICY_NOT_FOUND("IDA-KYE-006", "Partner Policy not found."), + KYC_TOKEN_INVALID_UIN_VID("IDA-KYE-007", "KYC Token does not belong to the input UIN/VID."), ID_KEY_BINDING_NOT_ALLOWED("IDA-IKB-001", "Key Binding not allowed for the Id."), CREATE_PUBLIC_KEY_OBJECT_ERROR("IDA-IKB-002", "Error creating Public Key object."), PUBLIC_KEY_BINDING_NOT_ALLOWED("IDA-IKB-003", "Publick Key already Binded to another Id."), IDENTITY_NAME_NOT_FOUND("IDA-IKB-004", "Identity Name not found."), CREATE_CERTIFICATE_OBJECT_ERROR("IDA-IKB-005", "Error creating Certificate object."), - TOKEN_AUTH_IDTYPE_MISMATCH("IDA-TOA-001", "Input Identity Type does not match Identity Type of Token Request"),; + + TOKEN_AUTH_IDTYPE_MISMATCH("IDA-TOA-001", "Input Identity Type does not match Identity Type of Token Request"), + + KEY_TYPE_NOT_SUPPORT("IDA-VCI-001", "Not Supported JWK Key Type."), + CREATE_VCI_PUBLIC_KEY_OBJECT_ERROR("IDA-VCI-002", "Error creating Public Key object."), + KEY_ALREADY_MAPPED_ERROR("IDA-VCI-003", "Error Key already mapped to different id/vid."), + VCI_NOT_SUPPORTED_ERROR("IDA-VCI-004", "Error VCI not supported."), + LDP_VC_GENERATION_FAILED("IDA-VCI-005", "Ldp VC generation Failed."); + private final String errorCode; private final String errorMessage; diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/RequestType.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/RequestType.java index 6f713d7c237..88733da11a2 100644 --- a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/RequestType.java +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/RequestType.java @@ -20,7 +20,8 @@ public enum RequestType { KYC_EXCHANGE_REQUEST("KYC-EXCHANGE","KYC Exchange Request"), IDENTITY_KEY_BINDING("IDENTITY-KEY-BINDING","Identity Key Binding Request"), TOKEN_REQUEST("TOKEN-REQUEST", "Token Request"), - TOKEN_AUTH("TOKEN-AUTH","Token based Authentication"); + TOKEN_AUTH("TOKEN-AUTH","Token based Authentication"), + VCI_EXCHANGE_REQUEST("VCI-EXCHANGE-REQUEST","VCI Exchange Request"); String type; String message; diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/VCFormats.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/VCFormats.java new file mode 100644 index 00000000000..83d90fc29ae --- /dev/null +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/VCFormats.java @@ -0,0 +1,18 @@ +package io.mosip.authentication.core.constant; + +public enum VCFormats { + LDP_VC("ldp_vc"), + JWT_VC_JSON("jwt_vc_json"), + JWT_VC_JSON_LD("jwt_vc_json-ld"), + MSO_MDOC("mso_mdoc"); + + private final String format; + + private VCFormats(String format) { + this.format = format; + } + + public String getFormat() { + return format; + } +} diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/VCStatus.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/VCStatus.java new file mode 100644 index 00000000000..b96ce536844 --- /dev/null +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/constant/VCStatus.java @@ -0,0 +1,24 @@ +package io.mosip.authentication.core.constant; + +public enum VCStatus { + + /** */ + ACTIVE("ACTIVE"), + + /** */ + INACTIVE("INACTIVE"), + + /** */ + REVOKED("REVOKED"); + + private String status; + + private VCStatus(String status) { + this.status = status; + } + + public String getStatus() { + return this.status; + } + +} diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/indauth/dto/VCResponseDTO.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/indauth/dto/VCResponseDTO.java new file mode 100644 index 00000000000..5be31b3b2f8 --- /dev/null +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/indauth/dto/VCResponseDTO.java @@ -0,0 +1,18 @@ +package io.mosip.authentication.core.indauth.dto; + +import lombok.Data; + +/** + * The class for VCResponseDTO Holds the values for Verifiable Credential response data. + * + * @author Mahammed Taheer + * + */ + +@Data +public class VCResponseDTO { + + /** The Variable to hold value of Verifiable Credentials data */ + private T verifiableCredentials; + +} diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/indauth/dto/VciCredentialsDefinitionRequestDTO.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/indauth/dto/VciCredentialsDefinitionRequestDTO.java new file mode 100644 index 00000000000..9d2667d0a1c --- /dev/null +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/indauth/dto/VciCredentialsDefinitionRequestDTO.java @@ -0,0 +1,26 @@ +package io.mosip.authentication.core.indauth.dto; + +import java.util.List; +import java.util.Map; + +import lombok.Data; + +/** + * The Class VciCredentialsDefinitionRequestDTO for credential definition input. + * + * @author Mahammed Taheer + * + */ +@Data +public class VciCredentialsDefinitionRequestDTO { + + /** */ + private Map credentialSubject; + + /** */ + private List type; + + /** */ + private List context; + +} diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/indauth/dto/VciExchangeRequestDTO.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/indauth/dto/VciExchangeRequestDTO.java new file mode 100644 index 00000000000..1b36f908830 --- /dev/null +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/indauth/dto/VciExchangeRequestDTO.java @@ -0,0 +1,42 @@ +package io.mosip.authentication.core.indauth.dto; + +import java.util.List; +import java.util.Map; + +import javax.validation.constraints.NotNull; + +import io.mosip.authentication.core.dto.ObjectWithMetadata; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * The class VciExchangeRequestDTO to holds the request parameters + * for VCI Exchange. + * + * @author Mahammed Taheer + * + */ +@Data +@EqualsAndHashCode(callSuper=true) +public class VciExchangeRequestDTO extends BaseRequestDTO implements ObjectWithMetadata { + + /** The Variable to hold value of kyc Token */ + @NotNull + private String vcAuthToken; + + /** The Variable to hold value of Credential Subject Id */ + @NotNull + private String credSubjectId; + + /** The Variable to hold value of VC Format type */ + @NotNull + private String vcFormat; + + /** The Variable to hold value of credential definition */ + private VciCredentialsDefinitionRequestDTO credentialsDefinition; + + /** The Variable to hold value of list of user selected locales */ + private List locales; + + private Map metadata; +} diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/indauth/dto/VciExchangeResponseDTO.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/indauth/dto/VciExchangeResponseDTO.java new file mode 100644 index 00000000000..f96da1b093d --- /dev/null +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/indauth/dto/VciExchangeResponseDTO.java @@ -0,0 +1,19 @@ +package io.mosip.authentication.core.indauth.dto; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * The Class For VciExchangeResponseDTO extending {@link BaseAuthResponseDTO} + * + * @author Mahammed Taheer + */ + +@Data +@EqualsAndHashCode(callSuper=true) +public class VciExchangeResponseDTO extends BaseAuthResponseDTO { + + /** The VCResponseDTO */ + private VCResponseDTO response; + +} diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/partner/dto/MispPolicyDTO.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/partner/dto/MispPolicyDTO.java index 4d4c050ac24..8798de4688f 100644 --- a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/partner/dto/MispPolicyDTO.java +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/partner/dto/MispPolicyDTO.java @@ -17,4 +17,6 @@ public class MispPolicyDTO { private boolean allowOTPRequestDelegation; private boolean allowKeyBindingDelegation; + + private boolean allowVciRequestDelegation; } diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/facade/KycFacade.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/facade/KycFacade.java index bdfd1342f5c..061275376af 100644 --- a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/facade/KycFacade.java +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/facade/KycFacade.java @@ -1,6 +1,7 @@ package io.mosip.authentication.core.spi.indauth.facade; import java.util.Map; + import javax.annotation.Nonnull; import io.mosip.authentication.core.dto.ObjectWithMetadata; @@ -8,9 +9,8 @@ import io.mosip.authentication.core.exception.IdAuthenticationDaoException; import io.mosip.authentication.core.indauth.dto.AuthRequestDTO; import io.mosip.authentication.core.indauth.dto.AuthResponseDTO; -import io.mosip.authentication.core.indauth.dto.BaseAuthResponseDTO; -import io.mosip.authentication.core.indauth.dto.EkycAuthRequestDTO; import io.mosip.authentication.core.indauth.dto.EKycAuthResponseDTO; +import io.mosip.authentication.core.indauth.dto.EkycAuthRequestDTO; import io.mosip.authentication.core.indauth.dto.KycAuthResponseDTO; import io.mosip.authentication.core.indauth.dto.KycExchangeRequestDTO; import io.mosip.authentication.core.indauth.dto.KycExchangeResponseDTO; diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/facade/VciFacade.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/facade/VciFacade.java new file mode 100644 index 00000000000..2fb379acea7 --- /dev/null +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/facade/VciFacade.java @@ -0,0 +1,32 @@ +package io.mosip.authentication.core.spi.indauth.facade; + +import java.util.Map; + +import io.mosip.authentication.core.dto.ObjectWithMetadata; +import io.mosip.authentication.core.exception.IdAuthenticationBusinessException; +import io.mosip.authentication.core.indauth.dto.VciExchangeRequestDTO; +import io.mosip.authentication.core.indauth.dto.VciExchangeResponseDTO; + +/** + * This class used to integrate with VCI service + * + * @author Mahammed Taheer + */ +public interface VciFacade { + + /** + * Process the VciExchangeRequestDTO to integrate with VciService. + * + * @param vciExchangeRequestDTO is DTO of VciExchangeRequestDTO + * @param partnerId the partner id + * @param oidcClientId the client id + * @param metadata the metadata + * @param requestWithMetadata the request with metadata + * @return the VCI Exchange response DTO + * @throws IdAuthenticationBusinessException the id authentication business + * exception + */ + VciExchangeResponseDTO processVciExchange(VciExchangeRequestDTO vciExchangeRequestDTO, + String partnerId, String oidcClientId, Map metadata, ObjectWithMetadata requestWithMetadata) throws IdAuthenticationBusinessException; + +} diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/service/KycService.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/service/KycService.java index dc34a2817fa..01dda454c43 100644 --- a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/service/KycService.java +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/service/KycService.java @@ -7,6 +7,7 @@ import io.mosip.authentication.core.exception.IdAuthenticationBusinessException; import io.mosip.authentication.core.indauth.dto.IdentityInfoDTO; +import io.mosip.authentication.core.indauth.dto.KycExchangeRequestDTO; import io.mosip.authentication.core.indauth.dto.EKycResponseDTO; /** @@ -76,5 +77,5 @@ String generateAndSaveKycToken(String idHash, String authToken, String oidcClien * exception */ String buildKycExchangeResponse(String subject, Map> idInfo, - List consentedAttributes, List locales, String idVid) throws IdAuthenticationBusinessException; + List consentedAttributes, List locales, String idVid, KycExchangeRequestDTO kycExchangeRequestDTO) throws IdAuthenticationBusinessException; } diff --git a/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/service/VciService.java b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/service/VciService.java new file mode 100644 index 00000000000..463ab775979 --- /dev/null +++ b/authentication/authentication-core/src/main/java/io/mosip/authentication/core/spi/indauth/service/VciService.java @@ -0,0 +1,47 @@ +package io.mosip.authentication.core.spi.indauth.service; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import io.mosip.authentication.core.exception.IdAuthenticationBusinessException; +import io.mosip.authentication.core.indauth.dto.IdentityInfoDTO; +import io.mosip.authentication.core.indauth.dto.VCResponseDTO; +import io.mosip.authentication.core.indauth.dto.VciExchangeRequestDTO; + +/** + * This interface is used to build Verifiable Credentials. + * + * @author Mahammed Taheer + */ +public interface VciService { + + /** + * Method used to add the Credential Subject Id in DB. + * + * @param credSubjectId the Credential Subject id of the identity + * @param idVidHash the Id/VID hash value + * @param tokenId the token id of the identity + * @return void + * @throws IdAuthenticationBusinessException the id authentication business + * exception + */ + public void addCredSubjectId(String credSubjectId, + String idVidHash, String tokenId, String oidcClientId) throws IdAuthenticationBusinessException; + + + /** + * Method to build the verifiable credentials. + * + * @param credSubjectId the Credential Subject id of the identity + * @param vcFormat VC format + * @param idInfo List of Identity Info of the user. + * @param locales locale data to be added in VC. + * @return VCResponseDTO VC Response based on requested format. + * @throws IdAuthenticationBusinessException the id authentication business + * exception + */ + public VCResponseDTO buildVerifiableCredentials(String credSubjectId, String vcFormat, + Map> idInfo, List locales, Set allowedAttributes, + VciExchangeRequestDTO vciExchangeRequestDTO, String psuToken) throws IdAuthenticationBusinessException; +} diff --git a/authentication/authentication-internal-service/Dockerfile b/authentication/authentication-internal-service/Dockerfile index ebb9bdc1c6f..7e27c6b8402 100644 --- a/authentication/authentication-internal-service/Dockerfile +++ b/authentication/authentication-internal-service/Dockerfile @@ -1,142 +1,142 @@ -FROM openjdk:11 - -ARG SOURCE -ARG COMMIT_HASH -ARG COMMIT_ID -ARG BUILD_TIME -LABEL source=${SOURCE} -LABEL commit_hash=${COMMIT_HASH} -LABEL commit_id=${COMMIT_ID} -LABEL build_time=${BUILD_TIME} - -# can be passed during Docker build as build time environment for github branch to pickup configuration from. -ARG spring_config_label - -# can be passed during Docker build as build time environment for spring profiles active -ARG active_profile - -# can be passed during Docker build as build time environment for config server URL -ARG spring_config_url - -#ARG bio_sdk_folder=mock/0.9 -ARG biosdk_zip_path - -ARG demosdk_zip_path - -# can be passed during Docker build as build time environment for hsm client zip file path -#ARG client_zip_path -ARG hsm_client_zip_path - -# can be passed during Docker build as build time environment for glowroot -ARG is_glowroot - -# can be passed during Docker build as build time environment for artifactory URL -ARG artifactory_url - -# environment variable to pass active profile such as DEV, QA etc at docker runtime -ENV active_profile_env=${active_profile} - -# environment variable to pass github branch to pickup configuration from, at docker runtime -ENV spring_config_label_env=${spring_config_label} - -# environment variable to pass spring configuration url, at docker runtime -ENV spring_config_url_env=${spring_config_url} - -# environment variable to pass glowroot, at docker runtime -ENV is_glowroot_env=${is_glowroot} - -# environment variable to pass artifactory url, at docker runtime -ENV artifactory_url_env=${artifactory_url} - -# environment variable to pass iam_adapter url, at docker runtime -ENV iam_adapter_url_env=${iam_adapter_url} - -#ENV bio_sdk_folder_env=${bio_sdk_folder} -ENV biosdk_zip_file_path=${biosdk_zip_path} - -ENV demosdk_zip_file_path=${demosdk_zip_path} - -# environment variable to pass hsm client zip file path, at docker runtime -#ENV zip_file_path=${client_zip_path} -ENV hsm_zip_file_path=${hsm_client_zip_path} - -# can be passed during Docker build as build time environment for github branch to pickup configuration from. -ARG container_user=mosip - -# can be passed during Docker build as build time environment for github branch to pickup configuration from. -ARG container_user_group=mosip - -# can be passed during Docker build as build time environment for github branch to pickup configuration from. -ARG container_user_uid=1001 - -# can be passed during Docker build as build time environment for github branch to pickup configuration from. -ARG container_user_gid=1001 - -ARG hsm_local_dir=hsm-client - -ENV hsm_local_dir_name=${hsm_local_dir} - -ARG biosdk_local_dir=biosdk-client - -ARG demosdk_local_dir=demosdk - -ENV biosdk_local_dir_name=${biosdk_local_dir} - -ENV demosdk_local_dir_name=${demosdk_local_dir} - -# install packages and create user -RUN apt-get -y update \ -&& apt-get install -y unzip sudo \ -&& groupadd -g ${container_user_gid} ${container_user_group} \ -&& useradd -u ${container_user_uid} -g ${container_user_group} -s /bin/sh -m ${container_user} \ -&& adduser ${container_user} sudo \ -&& echo "%sudo ALL=(ALL) NOPASSWD:/home/${container_user}/${hsm_local_dir}/install.sh" >> /etc/sudoers \ -&& echo "%sudo ALL=(ALL) NOPASSWD:/home/${container_user}/${biosdk_local_dir}/install.sh" >> /etc/sudoers - -# set working directory for the user -WORKDIR /home/${container_user} - -ENV work_dir=/home/${container_user} - -ARG loader_path=${work_dir}/additional_jars/ - -RUN mkdir -p ${loader_path} - -ENV loader_path_env=${loader_path} - -ENV current_module_env=authentication-internal-service - -ADD configure_start.sh configure_start.sh - -RUN chmod +x configure_start.sh - -ADD target/${current_module_env}-*.jar ${current_module_env}.jar - -EXPOSE 8093 - -EXPOSE 9010 - -# change permissions of file inside working dir -RUN chown -R ${container_user}:${container_user} /home/${container_user} - -# select container user for all tasks -USER ${container_user_uid}:${container_user_gid} - -ENTRYPOINT [ "./configure_start.sh" ] - -CMD if [ "$is_glowroot_env" = "present" ]; then \ - wget -q --show-progress "${artifactory_url_env}"/artifactory/libs-release-local/io/mosip/authentication/authentication-ref-impl/authentication-childauthfilter-impl.jar -O "${loader_path_env}"/authentication-childauthfilter-impl.jar ; \ - wget -q --show-progress "${artifactory_url_env}"/artifactory/libs-release-local/io/mosip/testing/glowroot.zip ; \ - unzip glowroot.zip ; \ - rm -rf glowroot.zip ; \ - sed -i "s//${current_module_env}/g" glowroot/glowroot.properties ; \ - wget -q --show-progress "${iam_adapter_url_env}" -O "${loader_path_env}"/kernel-auth-adapter.jar; \ - java -jar -Djava.security.debug=sunpkcs11 -javaagent:glowroot/glowroot.jar -Dspring.cloud.config.label="${spring_config_label_env}" -Dspring.profiles.active="${active_profile_env}" -Dspring.cloud.config.uri="${spring_config_url_env}" -Dloader.path="${loader_path_env}" -Dfile.encoding="UTF-8" ${current_module_env}.jar ; \ - else \ - wget -q --show-progress "${artifactory_url_env}"/artifactory/libs-release-local/io/mosip/authentication/authentication-ref-impl/authentication-childauthfilter-impl.jar -O "${loader_path_env}"/authentication-childauthfilter-impl.jar ; \ - wget -q --show-progress "${iam_adapter_url_env}" -O "${loader_path_env}"/kernel-auth-adapter.jar; \ - java -jar -Djava.security.debug=sunpkcs11 -Dspring.cloud.config.label="${spring_config_label_env}" -Dspring.profiles.active="${active_profile_env}" -Dspring.cloud.config.uri="${spring_config_url_env}" -Dloader.path="${loader_path_env}" -Dfile.encoding="UTF-8" ${current_module_env}.jar ; \ - fi - -#Sample docker run command: +FROM openjdk:11 + +ARG SOURCE +ARG COMMIT_HASH +ARG COMMIT_ID +ARG BUILD_TIME +LABEL source=${SOURCE} +LABEL commit_hash=${COMMIT_HASH} +LABEL commit_id=${COMMIT_ID} +LABEL build_time=${BUILD_TIME} + +# can be passed during Docker build as build time environment for github branch to pickup configuration from. +ARG spring_config_label + +# can be passed during Docker build as build time environment for spring profiles active +ARG active_profile + +# can be passed during Docker build as build time environment for config server URL +ARG spring_config_url + +#ARG bio_sdk_folder=mock/0.9 +ARG biosdk_zip_path + +ARG demosdk_zip_path + +# can be passed during Docker build as build time environment for hsm client zip file path +#ARG client_zip_path +ARG hsm_client_zip_path + +# can be passed during Docker build as build time environment for glowroot +ARG is_glowroot + +# can be passed during Docker build as build time environment for artifactory URL +ARG artifactory_url + +# environment variable to pass active profile such as DEV, QA etc at docker runtime +ENV active_profile_env=${active_profile} + +# environment variable to pass github branch to pickup configuration from, at docker runtime +ENV spring_config_label_env=${spring_config_label} + +# environment variable to pass spring configuration url, at docker runtime +ENV spring_config_url_env=${spring_config_url} + +# environment variable to pass glowroot, at docker runtime +ENV is_glowroot_env=${is_glowroot} + +# environment variable to pass artifactory url, at docker runtime +ENV artifactory_url_env=${artifactory_url} + +# environment variable to pass iam_adapter url, at docker runtime +ENV iam_adapter_url_env=${iam_adapter_url} + +#ENV bio_sdk_folder_env=${bio_sdk_folder} +ENV biosdk_zip_file_path=${biosdk_zip_path} + +ENV demosdk_zip_file_path=${demosdk_zip_path} + +# environment variable to pass hsm client zip file path, at docker runtime +#ENV zip_file_path=${client_zip_path} +ENV hsm_zip_file_path=${hsm_client_zip_path} + +# can be passed during Docker build as build time environment for github branch to pickup configuration from. +ARG container_user=mosip + +# can be passed during Docker build as build time environment for github branch to pickup configuration from. +ARG container_user_group=mosip + +# can be passed during Docker build as build time environment for github branch to pickup configuration from. +ARG container_user_uid=1001 + +# can be passed during Docker build as build time environment for github branch to pickup configuration from. +ARG container_user_gid=1001 + +ARG hsm_local_dir=hsm-client + +ENV hsm_local_dir_name=${hsm_local_dir} + +ARG biosdk_local_dir=biosdk-client + +ARG demosdk_local_dir=demosdk + +ENV biosdk_local_dir_name=${biosdk_local_dir} + +ENV demosdk_local_dir_name=${demosdk_local_dir} + +# install packages and create user +RUN apt-get -y update \ +&& apt-get install -y unzip sudo \ +&& groupadd -g ${container_user_gid} ${container_user_group} \ +&& useradd -u ${container_user_uid} -g ${container_user_group} -s /bin/sh -m ${container_user} \ +&& adduser ${container_user} sudo \ +&& echo "%sudo ALL=(ALL) NOPASSWD:/home/${container_user}/${hsm_local_dir}/install.sh" >> /etc/sudoers \ +&& echo "%sudo ALL=(ALL) NOPASSWD:/home/${container_user}/${biosdk_local_dir}/install.sh" >> /etc/sudoers + +# set working directory for the user +WORKDIR /home/${container_user} + +ENV work_dir=/home/${container_user} + +ARG loader_path=${work_dir}/additional_jars/ + +RUN mkdir -p ${loader_path} + +ENV loader_path_env=${loader_path} + +ENV current_module_env=authentication-internal-service + +ADD configure_start.sh configure_start.sh + +RUN chmod +x configure_start.sh + +ADD target/${current_module_env}-*.jar ${current_module_env}.jar + +EXPOSE 8093 + +EXPOSE 9010 + +# change permissions of file inside working dir +RUN chown -R ${container_user}:${container_user} /home/${container_user} + +# select container user for all tasks +USER ${container_user_uid}:${container_user_gid} + +ENTRYPOINT [ "./configure_start.sh" ] + +CMD if [ "$is_glowroot_env" = "present" ]; then \ + wget -q "${artifactory_url_env}"/artifactory/libs-release-local/io/mosip/authentication/authentication-ref-impl/authentication-childauthfilter-impl.jar -O "${loader_path_env}"/authentication-childauthfilter-impl.jar ; \ + wget -q "${artifactory_url_env}"/artifactory/libs-release-local/io/mosip/testing/glowroot.zip ; \ + unzip glowroot.zip ; \ + rm -rf glowroot.zip ; \ + sed -i "s//${current_module_env}/g" glowroot/glowroot.properties ; \ + wget -q "${iam_adapter_url_env}" -O "${loader_path_env}"/kernel-auth-adapter.jar; \ + java -jar -Djava.security.debug=sunpkcs11 -javaagent:glowroot/glowroot.jar -Dspring.cloud.config.label="${spring_config_label_env}" -Dspring.profiles.active="${active_profile_env}" -Dspring.cloud.config.uri="${spring_config_url_env}" -Dloader.path="${loader_path_env}" -Dfile.encoding="UTF-8" ${current_module_env}.jar ; \ + else \ + wget -q "${artifactory_url_env}"/artifactory/libs-release-local/io/mosip/authentication/authentication-ref-impl/authentication-childauthfilter-impl.jar -O "${loader_path_env}"/authentication-childauthfilter-impl.jar ; \ + wget -q "${iam_adapter_url_env}" -O "${loader_path_env}"/kernel-auth-adapter.jar; \ + java -jar -Djava.security.debug=sunpkcs11 -Dspring.cloud.config.label="${spring_config_label_env}" -Dspring.profiles.active="${active_profile_env}" -Dspring.cloud.config.uri="${spring_config_url_env}" -Dloader.path="${loader_path_env}" -Dfile.encoding="UTF-8" ${current_module_env}.jar ; \ + fi + +#Sample docker run command: # sudo docker run --rm -it -e artifactory_url_env="http://artifactory" -e spring_config_label_env="1.0.9" -e active_profile_env="dev" -e spring_config_url_env="http://config-server/config" -e PKCS11_PROXY_SOCKET=tcp://softhsm-ida:5666 -p 8093:8093 authentication-internal-service:1.0.9 \ No newline at end of file diff --git a/authentication/authentication-internal-service/src/main/java/io/mosip/authentication/internal/service/InternalAuthenticationApplication.java b/authentication/authentication-internal-service/src/main/java/io/mosip/authentication/internal/service/InternalAuthenticationApplication.java index 8569c5b04eb..169c4a4feb6 100644 --- a/authentication/authentication-internal-service/src/main/java/io/mosip/authentication/internal/service/InternalAuthenticationApplication.java +++ b/authentication/authentication-internal-service/src/main/java/io/mosip/authentication/internal/service/InternalAuthenticationApplication.java @@ -1,154 +1,156 @@ -package io.mosip.authentication.internal.service; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.FilterType; -import org.springframework.context.annotation.Import; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; - -import io.mosip.authentication.common.manager.IdAuthFraudAnalysisEventManager; -import io.mosip.authentication.common.service.builder.MatchInputBuilder; -import io.mosip.authentication.common.service.cache.MasterDataCache; -import io.mosip.authentication.common.service.config.IDAMappingConfig; -import io.mosip.authentication.common.service.config.SwaggerConfig; -import io.mosip.authentication.common.service.exception.IdAuthExceptionHandler; -import io.mosip.authentication.common.service.facade.AuthFacadeImpl; -import io.mosip.authentication.common.service.factory.AuditRequestFactory; -import io.mosip.authentication.common.service.factory.RestRequestFactory; -import io.mosip.authentication.common.service.helper.AuditHelper; -import io.mosip.authentication.common.service.helper.AuthTransactionHelper; -import io.mosip.authentication.common.service.helper.IdInfoHelper; -import io.mosip.authentication.common.service.helper.InternalRestHelperConfig; -import io.mosip.authentication.common.service.helper.WebSubHelper; -import io.mosip.authentication.common.service.impl.AuthContextClazzRefProvider; -import io.mosip.authentication.common.service.impl.AuthTxnServiceImpl; -import io.mosip.authentication.common.service.impl.AuthtypeStatusImpl; -import io.mosip.authentication.common.service.impl.BioAuthServiceImpl; -import io.mosip.authentication.common.service.impl.DemoAuthServiceImpl; -import io.mosip.authentication.common.service.impl.IdInfoFetcherImpl; -import io.mosip.authentication.common.service.impl.IdServiceImpl; -import io.mosip.authentication.common.service.impl.KeyBindedTokenAuthServiceImpl; -import io.mosip.authentication.common.service.impl.OTPAuthServiceImpl; -import io.mosip.authentication.common.service.impl.OTPServiceImpl; -import io.mosip.authentication.common.service.impl.hotlist.HotlistServiceImpl; -import io.mosip.authentication.common.service.impl.idevent.CredentialStoreServiceImpl; -import io.mosip.authentication.common.service.impl.idevent.IdChangeEventHandlerServiceImpl; -import io.mosip.authentication.common.service.impl.masterdata.MasterDataCacheUpdateServiceImpl; -import io.mosip.authentication.common.service.impl.notification.NotificationServiceImpl; -import io.mosip.authentication.common.service.impl.patrner.PartnerCACertEventServiceImpl; -import io.mosip.authentication.common.service.impl.patrner.PartnerServiceImpl; -import io.mosip.authentication.common.service.integration.CredentialRequestManager; -import io.mosip.authentication.common.service.integration.DataShareManager; -import io.mosip.authentication.common.service.integration.IdTemplateManager; -import io.mosip.authentication.common.service.integration.KeyManager; -import io.mosip.authentication.common.service.integration.MasterDataManager; -import io.mosip.authentication.common.service.integration.NotificationManager; -import io.mosip.authentication.common.service.integration.OTPManager; -import io.mosip.authentication.common.service.integration.PartnerServiceManager; -import io.mosip.authentication.common.service.integration.TokenIdManager; -import io.mosip.authentication.common.service.util.BioMatcherUtil; -import io.mosip.authentication.common.service.util.EnvUtil; -import io.mosip.authentication.common.service.util.IdaRequestResponsConsumerUtil; -import io.mosip.authentication.common.service.util.KeyBindedTokenMatcherUtil; -import io.mosip.authentication.common.service.validator.AuthFiltersValidator; -import io.mosip.authentication.common.service.validator.OTPRequestValidator; -import io.mosip.authentication.common.service.websub.impl.AuthTransactionStatusEventPublisher; -import io.mosip.authentication.common.service.websub.impl.AuthTypeStatusEventPublisher; -import io.mosip.authentication.common.service.websub.impl.AuthTypeStatusEventSubscriber; -import io.mosip.authentication.common.service.websub.impl.CredentialStoreStatusEventPublisher; -import io.mosip.authentication.common.service.websub.impl.HotlistEventInitializer; -import io.mosip.authentication.common.service.websub.impl.IdAuthFraudAnalysisEventPublisher; -import io.mosip.authentication.common.service.websub.impl.IdChangeEventsInitializer; -import io.mosip.authentication.common.service.websub.impl.MasterDataUpdateEventInitializer; -import io.mosip.authentication.common.service.websub.impl.PartnerCACertEventInitializer; -import io.mosip.authentication.common.service.websub.impl.PartnerServiceEventsInitializer; -import io.mosip.authentication.core.util.DemoMatcherUtil; -import io.mosip.authentication.core.util.DemoNormalizer; -import io.mosip.authentication.core.util.IdTypeUtil; -import io.mosip.authentication.core.util.IdValidationUtil; -import io.mosip.authentication.internal.service.batch.CredentialStoreJobExecutionListener; -import io.mosip.authentication.internal.service.manager.InternalAuthSecurityManager; -import io.mosip.kernel.biosdk.provider.factory.BioAPIFactory; -import io.mosip.kernel.biosdk.provider.impl.BioProviderImpl_V_0_8; -import io.mosip.kernel.biosdk.provider.impl.BioProviderImpl_V_0_9; -import io.mosip.kernel.cbeffutil.impl.CbeffImpl; -import io.mosip.kernel.core.retry.RetryAspect; -import io.mosip.kernel.core.retry.RetryConfig; -import io.mosip.kernel.core.retry.RetryListenerImpl; -import io.mosip.kernel.core.util.RetryUtil; -import io.mosip.kernel.crypto.jce.core.CryptoCore; -import io.mosip.kernel.cryptomanager.controller.CryptomanagerController; -import io.mosip.kernel.cryptomanager.service.impl.CryptomanagerServiceImpl; -import io.mosip.kernel.cryptomanager.util.CryptomanagerUtils; -import io.mosip.kernel.dataaccess.hibernate.config.HibernateDaoConfig; -import io.mosip.kernel.keygenerator.bouncycastle.KeyGenerator; -import io.mosip.kernel.keymanager.hsm.impl.KeyStoreImpl; -import io.mosip.kernel.keymanagerservice.controller.KeymanagerController; -import io.mosip.kernel.keymanagerservice.entity.CACertificateStore; -import io.mosip.kernel.keymanagerservice.helper.KeymanagerDBHelper; -import io.mosip.kernel.keymanagerservice.helper.SessionKeyDecrytorHelper; -import io.mosip.kernel.keymanagerservice.service.impl.KeymanagerServiceImpl; -import io.mosip.kernel.keymanagerservice.util.KeymanagerUtil; -import io.mosip.kernel.partnercertservice.controller.PartnerCertManagerController; -import io.mosip.kernel.partnercertservice.helper.PartnerCertManagerDBHelper; -import io.mosip.kernel.partnercertservice.service.impl.PartnerCertificateManagerServiceImpl; -import io.mosip.kernel.pinvalidator.impl.PinValidatorImpl; -import io.mosip.kernel.signature.controller.SignatureController; -import io.mosip.kernel.signature.service.impl.SignatureServiceImpl; -import io.mosip.kernel.templatemanager.velocity.builder.TemplateManagerBuilderImpl; -import io.mosip.kernel.tokenidgenerator.generator.TokenIDGenerator; -import io.mosip.kernel.zkcryptoservice.service.impl.ZKCryptoManagerServiceImpl; - -/** - * Spring-boot class for ID Authentication Application. - * - * @author Dinesh Karuppiah - */ -@SpringBootApplication(exclude = { HibernateDaoConfig.class }) -@Import(value = { IdValidationUtil.class, IDAMappingConfig.class, KeyBindedTokenAuthServiceImpl.class, - KeyManager.class, AuthContextClazzRefProvider.class, - RestRequestFactory.class, IdInfoFetcherImpl.class, OTPManager.class, MasterDataManager.class, - MasterDataCache.class, MasterDataCacheUpdateServiceImpl.class, MasterDataUpdateEventInitializer.class, MatchInputBuilder.class, - NotificationManager.class, NotificationServiceImpl.class, IdTemplateManager.class, TemplateManagerBuilderImpl.class, - IdAuthExceptionHandler.class, AuthFacadeImpl.class, OTPAuthServiceImpl.class, IdInfoHelper.class, CbeffImpl.class, - IdServiceImpl.class, AuditRequestFactory.class, DemoAuthServiceImpl.class, BioAuthServiceImpl.class, TokenIdManager.class, - SwaggerConfig.class, AuditHelper.class, PinValidatorImpl.class, BioMatcherUtil.class, BioAPIFactory.class, - BioProviderImpl_V_0_8.class, BioProviderImpl_V_0_9.class, OTPServiceImpl.class, - OTPRequestValidator.class, InternalAuthSecurityManager.class, AuthTxnServiceImpl.class, AuthtypeStatusImpl.class, - CryptoCore.class, PartnerServiceImpl.class, CryptomanagerServiceImpl.class, KeyGenerator.class, CryptomanagerUtils.class, - KeymanagerServiceImpl.class, KeymanagerUtil.class, IdChangeEventHandlerServiceImpl.class, SignatureServiceImpl.class, - KeyStoreImpl.class, KeymanagerDBHelper.class, ZKCryptoManagerServiceImpl.class, PartnerServiceManager.class, - DataShareManager.class, TokenIDGenerator.class, IdTypeUtil.class, WebSubHelper.class, - PartnerCACertEventServiceImpl.class, PartnerCertificateManagerServiceImpl.class, PartnerCertManagerDBHelper.class, AuthTypeStatusEventSubscriber.class, - IdChangeEventsInitializer.class, SignatureController.class, CryptomanagerController.class, KeymanagerController.class, - CACertificateStore.class, PartnerCACertEventInitializer.class, PartnerCertManagerController.class, RetryConfig.class, - RetryUtil.class, RetryListenerImpl.class, RetryAspect.class, CredentialStoreServiceImpl.class, - CredentialStoreJobExecutionListener.class, HotlistServiceImpl.class, HotlistEventInitializer.class, - AuthTransactionHelper.class, CredentialStoreStatusEventPublisher.class, AuthTypeStatusEventPublisher.class, - AuthTransactionStatusEventPublisher.class, PartnerServiceEventsInitializer.class, CredentialRequestManager.class, - DemoNormalizer.class, DemoMatcherUtil.class, IdAuthFraudAnalysisEventManager.class, - IdAuthFraudAnalysisEventPublisher.class, AuthFiltersValidator.class, SessionKeyDecrytorHelper.class, InternalRestHelperConfig.class, IdaRequestResponsConsumerUtil.class, - io.mosip.kernel.cryptomanager.dto.AuthorizedRolesDTO.class, - io.mosip.kernel.keymanagerservice.dto.AuthorizedRolesDTO.class, - io.mosip.kernel.partnercertservice.dto.AuthorizedRolesDTO.class, - io.mosip.kernel.signature.dto.AuthorizedRolesDTO.class, - EnvUtil.class, KeyBindedTokenMatcherUtil.class }) -@ComponentScan(basePackages = { "io.mosip.authentication.internal.service.*", "${mosip.auth.adapter.impl.basepackage}", - "io.mosip.kernel.core.logger.config", - "io.mosip.authentication.common.service.config" }, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = { - "io.mosip.idrepository.core.config.IdRepoDataSourceConfig.*" })) -@EnableJpaRepositories(basePackages = { "io.mosip.authentication.common.service.repository.*", - "io.mosip.kernel.keymanagerservice.repository.*" }) -public class InternalAuthenticationApplication { - - /** - * The main method. - * - * @param args the arguments - */ - public static void main(String[] args) { - SpringApplication.run(InternalAuthenticationApplication.class, args); - } - -} +package io.mosip.authentication.internal.service; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import org.springframework.context.annotation.Import; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +import io.mosip.authentication.common.manager.IdAuthFraudAnalysisEventManager; +import io.mosip.authentication.common.service.builder.MatchInputBuilder; +import io.mosip.authentication.common.service.cache.MasterDataCache; +import io.mosip.authentication.common.service.config.IDAMappingConfig; +import io.mosip.authentication.common.service.config.SwaggerConfig; +import io.mosip.authentication.common.service.exception.IdAuthExceptionHandler; +import io.mosip.authentication.common.service.facade.AuthFacadeImpl; +import io.mosip.authentication.common.service.factory.AuditRequestFactory; +import io.mosip.authentication.common.service.factory.RestRequestFactory; +import io.mosip.authentication.common.service.helper.AuditHelper; +import io.mosip.authentication.common.service.helper.AuthTransactionHelper; +import io.mosip.authentication.common.service.helper.IdInfoHelper; +import io.mosip.authentication.common.service.helper.InternalRestHelperConfig; +import io.mosip.authentication.common.service.helper.WebSubHelper; +import io.mosip.authentication.common.service.impl.AuthContextClazzRefProvider; +import io.mosip.authentication.common.service.impl.AuthTxnServiceImpl; +import io.mosip.authentication.common.service.impl.AuthtypeStatusImpl; +import io.mosip.authentication.common.service.impl.BioAuthServiceImpl; +import io.mosip.authentication.common.service.impl.DemoAuthServiceImpl; +import io.mosip.authentication.common.service.impl.IdInfoFetcherImpl; +import io.mosip.authentication.common.service.impl.IdServiceImpl; +import io.mosip.authentication.common.service.impl.KeyBindedTokenAuthServiceImpl; +import io.mosip.authentication.common.service.impl.OTPAuthServiceImpl; +import io.mosip.authentication.common.service.impl.OTPServiceImpl; +import io.mosip.authentication.common.service.impl.hotlist.HotlistServiceImpl; +import io.mosip.authentication.common.service.impl.idevent.CredentialStoreServiceImpl; +import io.mosip.authentication.common.service.impl.idevent.IdChangeEventHandlerServiceImpl; +import io.mosip.authentication.common.service.impl.masterdata.MasterDataCacheUpdateServiceImpl; +import io.mosip.authentication.common.service.impl.notification.NotificationServiceImpl; +import io.mosip.authentication.common.service.impl.patrner.PartnerCACertEventServiceImpl; +import io.mosip.authentication.common.service.impl.patrner.PartnerServiceImpl; +import io.mosip.authentication.common.service.integration.CredentialRequestManager; +import io.mosip.authentication.common.service.integration.DataShareManager; +import io.mosip.authentication.common.service.integration.IdTemplateManager; +import io.mosip.authentication.common.service.integration.KeyManager; +import io.mosip.authentication.common.service.integration.MasterDataManager; +import io.mosip.authentication.common.service.integration.NotificationManager; +import io.mosip.authentication.common.service.integration.OTPManager; +import io.mosip.authentication.common.service.integration.PartnerServiceManager; +import io.mosip.authentication.common.service.integration.TokenIdManager; +import io.mosip.authentication.common.service.util.BioMatcherUtil; +import io.mosip.authentication.common.service.util.EnvUtil; +import io.mosip.authentication.common.service.util.IdaRequestResponsConsumerUtil; +import io.mosip.authentication.common.service.util.KeyBindedTokenMatcherUtil; +import io.mosip.authentication.common.service.validator.AuthFiltersValidator; +import io.mosip.authentication.common.service.validator.OTPRequestValidator; +import io.mosip.authentication.common.service.websub.impl.AuthTransactionStatusEventPublisher; +import io.mosip.authentication.common.service.websub.impl.AuthTypeStatusEventPublisher; +import io.mosip.authentication.common.service.websub.impl.AuthTypeStatusEventSubscriber; +import io.mosip.authentication.common.service.websub.impl.CredentialStoreStatusEventPublisher; +import io.mosip.authentication.common.service.websub.impl.HotlistEventInitializer; +import io.mosip.authentication.common.service.websub.impl.IdAuthFraudAnalysisEventPublisher; +import io.mosip.authentication.common.service.websub.impl.IdChangeEventsInitializer; +import io.mosip.authentication.common.service.websub.impl.MasterDataUpdateEventInitializer; +import io.mosip.authentication.common.service.websub.impl.PartnerCACertEventInitializer; +import io.mosip.authentication.common.service.websub.impl.PartnerServiceEventsInitializer; +import io.mosip.authentication.core.util.DemoMatcherUtil; +import io.mosip.authentication.core.util.DemoNormalizer; +import io.mosip.authentication.core.util.IdTypeUtil; +import io.mosip.authentication.core.util.IdValidationUtil; +import io.mosip.authentication.internal.service.batch.CredentialStoreJobExecutionListener; +import io.mosip.authentication.internal.service.manager.InternalAuthSecurityManager; +import io.mosip.kernel.biosdk.provider.factory.BioAPIFactory; +import io.mosip.kernel.biosdk.provider.impl.BioProviderImpl_V_0_8; +import io.mosip.kernel.biosdk.provider.impl.BioProviderImpl_V_0_9; +import io.mosip.kernel.cbeffutil.impl.CbeffImpl; +import io.mosip.kernel.core.retry.RetryAspect; +import io.mosip.kernel.core.retry.RetryConfig; +import io.mosip.kernel.core.retry.RetryListenerImpl; +import io.mosip.kernel.core.util.RetryUtil; +import io.mosip.kernel.crypto.jce.core.CryptoCore; +import io.mosip.kernel.cryptomanager.controller.CryptomanagerController; +import io.mosip.kernel.cryptomanager.service.impl.CryptomanagerServiceImpl; +import io.mosip.kernel.cryptomanager.util.CryptomanagerUtils; +import io.mosip.kernel.dataaccess.hibernate.config.HibernateDaoConfig; +import io.mosip.kernel.keygenerator.bouncycastle.KeyGenerator; +import io.mosip.kernel.keymanager.hsm.health.HSMHealthCheck; +import io.mosip.kernel.keymanager.hsm.impl.KeyStoreImpl; +import io.mosip.kernel.keymanagerservice.controller.KeymanagerController; +import io.mosip.kernel.keymanagerservice.entity.CACertificateStore; +import io.mosip.kernel.keymanagerservice.helper.KeymanagerDBHelper; +import io.mosip.kernel.keymanagerservice.helper.PrivateKeyDecryptorHelper; +import io.mosip.kernel.keymanagerservice.helper.SessionKeyDecrytorHelper; +import io.mosip.kernel.keymanagerservice.service.impl.KeymanagerServiceImpl; +import io.mosip.kernel.keymanagerservice.util.KeymanagerUtil; +import io.mosip.kernel.partnercertservice.controller.PartnerCertManagerController; +import io.mosip.kernel.partnercertservice.helper.PartnerCertManagerDBHelper; +import io.mosip.kernel.partnercertservice.service.impl.PartnerCertificateManagerServiceImpl; +import io.mosip.kernel.pinvalidator.impl.PinValidatorImpl; +import io.mosip.kernel.signature.controller.SignatureController; +import io.mosip.kernel.signature.service.impl.SignatureServiceImpl; +import io.mosip.kernel.templatemanager.velocity.builder.TemplateManagerBuilderImpl; +import io.mosip.kernel.tokenidgenerator.generator.TokenIDGenerator; +import io.mosip.kernel.zkcryptoservice.service.impl.ZKCryptoManagerServiceImpl; + +/** + * Spring-boot class for ID Authentication Application. + * + * @author Dinesh Karuppiah + */ +@SpringBootApplication(exclude = { HibernateDaoConfig.class }) +@Import(value = { IdValidationUtil.class, IDAMappingConfig.class, KeyBindedTokenAuthServiceImpl.class, + KeyManager.class, AuthContextClazzRefProvider.class, + RestRequestFactory.class, IdInfoFetcherImpl.class, OTPManager.class, MasterDataManager.class, + MasterDataCache.class, MasterDataCacheUpdateServiceImpl.class, MasterDataUpdateEventInitializer.class, MatchInputBuilder.class, + NotificationManager.class, NotificationServiceImpl.class, IdTemplateManager.class, TemplateManagerBuilderImpl.class, + IdAuthExceptionHandler.class, AuthFacadeImpl.class, OTPAuthServiceImpl.class, IdInfoHelper.class, CbeffImpl.class, + IdServiceImpl.class, AuditRequestFactory.class, DemoAuthServiceImpl.class, BioAuthServiceImpl.class, TokenIdManager.class, + SwaggerConfig.class, AuditHelper.class, PinValidatorImpl.class, BioMatcherUtil.class, BioAPIFactory.class, + BioProviderImpl_V_0_8.class, BioProviderImpl_V_0_9.class, OTPServiceImpl.class, + OTPRequestValidator.class, InternalAuthSecurityManager.class, AuthTxnServiceImpl.class, AuthtypeStatusImpl.class, + CryptoCore.class, PartnerServiceImpl.class, CryptomanagerServiceImpl.class, KeyGenerator.class, CryptomanagerUtils.class, + KeymanagerServiceImpl.class, KeymanagerUtil.class, IdChangeEventHandlerServiceImpl.class, SignatureServiceImpl.class, + KeyStoreImpl.class, KeymanagerDBHelper.class, ZKCryptoManagerServiceImpl.class, PartnerServiceManager.class, + DataShareManager.class, TokenIDGenerator.class, IdTypeUtil.class, WebSubHelper.class, + PartnerCACertEventServiceImpl.class, PartnerCertificateManagerServiceImpl.class, PartnerCertManagerDBHelper.class, AuthTypeStatusEventSubscriber.class, + IdChangeEventsInitializer.class, SignatureController.class, CryptomanagerController.class, KeymanagerController.class, + CACertificateStore.class, PartnerCACertEventInitializer.class, PartnerCertManagerController.class, RetryConfig.class, + RetryUtil.class, RetryListenerImpl.class, RetryAspect.class, CredentialStoreServiceImpl.class, + CredentialStoreJobExecutionListener.class, HotlistServiceImpl.class, HotlistEventInitializer.class, + AuthTransactionHelper.class, CredentialStoreStatusEventPublisher.class, AuthTypeStatusEventPublisher.class, + AuthTransactionStatusEventPublisher.class, PartnerServiceEventsInitializer.class, CredentialRequestManager.class, + DemoNormalizer.class, DemoMatcherUtil.class, IdAuthFraudAnalysisEventManager.class, + IdAuthFraudAnalysisEventPublisher.class, AuthFiltersValidator.class, SessionKeyDecrytorHelper.class, InternalRestHelperConfig.class, IdaRequestResponsConsumerUtil.class, + io.mosip.kernel.cryptomanager.dto.AuthorizedRolesDTO.class, + io.mosip.kernel.keymanagerservice.dto.AuthorizedRolesDTO.class, + io.mosip.kernel.partnercertservice.dto.AuthorizedRolesDTO.class, + io.mosip.kernel.signature.dto.AuthorizedRolesDTO.class, + EnvUtil.class, KeyBindedTokenMatcherUtil.class, HSMHealthCheck.class, PrivateKeyDecryptorHelper.class }) +@ComponentScan(basePackages = { "io.mosip.authentication.internal.service.*", "${mosip.auth.adapter.impl.basepackage}", + "io.mosip.kernel.core.logger.config", + "io.mosip.authentication.common.service.config" }, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = { + "io.mosip.idrepository.core.config.IdRepoDataSourceConfig.*" })) +@EnableJpaRepositories(basePackages = { "io.mosip.authentication.common.service.repository.*", + "io.mosip.kernel.keymanagerservice.repository.*" }) +public class InternalAuthenticationApplication { + + /** + * The main method. + * + * @param args the arguments + */ + public static void main(String[] args) { + SpringApplication.run(InternalAuthenticationApplication.class, args); + } + +} diff --git a/authentication/authentication-otp-service/Dockerfile b/authentication/authentication-otp-service/Dockerfile index ab421840c93..9228889b97c 100644 --- a/authentication/authentication-otp-service/Dockerfile +++ b/authentication/authentication-otp-service/Dockerfile @@ -1,123 +1,123 @@ -FROM openjdk:11 - -ARG SOURCE -ARG COMMIT_HASH -ARG COMMIT_ID -ARG BUILD_TIME -LABEL source=${SOURCE} -LABEL commit_hash=${COMMIT_HASH} -LABEL commit_id=${COMMIT_ID} -LABEL build_time=${BUILD_TIME} - -# can be passed during Docker build as build time environment for github branch to pickup configuration from. -ARG spring_config_label - -# can be passed during Docker build as build time environment for spring profiles active -ARG active_profile - -# can be passed during Docker build as build time environment for config server URL -ARG spring_config_url - -# can be passed during Docker build as build time environment for hsm client zip file path -#ARG client_zip_path -ARG hsm_client_zip_path - -# can be passed during Docker build as build time environment for glowroot -ARG is_glowroot - -# can be passed during Docker build as build time environment for artifactory URL -ARG artifactory_url - -# environment variable to pass active profile such as DEV, QA etc at docker runtime -ENV active_profile_env=${active_profile} - -# environment variable to pass github branch to pickup configuration from, at docker runtime -ENV spring_config_label_env=${spring_config_label} - -# environment variable to pass spring configuration url, at docker runtime -ENV spring_config_url_env=${spring_config_url} - -# environment variable to pass glowroot, at docker runtime -ENV is_glowroot_env=${is_glowroot} - -# environment variable to pass artifactory url, at docker runtime -ENV artifactory_url_env=${artifactory_url} - -# environment variable to pass iam_adapter url, at docker runtime -ENV iam_adapter_url_env=${iam_adapter_url} - -# environment variable to pass hsm client zip file path, at docker runtime -#ENV zip_file_path=${client_zip_path} -ENV hsm_zip_file_path=${hsm_client_zip_path} - -#ENV work_dir_env=/ - -# can be passed during Docker build as build time environment for github branch to pickup configuration from. -ARG container_user=mosip - -# can be passed during Docker build as build time environment for github branch to pickup configuration from. -ARG container_user_group=mosip - -# can be passed during Docker build as build time environment for github branch to pickup configuration from. -ARG container_user_uid=1001 - -# can be passed during Docker build as build time environment for github branch to pickup configuration from. -ARG container_user_gid=1001 - -ARG hsm_local_dir=hsm-client - -ENV hsm_local_dir_name=${hsm_local_dir} - -# install packages and create user -RUN apt-get -y update \ -&& apt-get install -y unzip sudo \ -&& groupadd -g ${container_user_gid} ${container_user_group} \ -&& useradd -u ${container_user_uid} -g ${container_user_group} -s /bin/sh -m ${container_user} \ -&& adduser ${container_user} sudo \ -&& echo "%sudo ALL=(ALL) NOPASSWD:/home/${container_user}/${hsm_local_dir}/install.sh" >> /etc/sudoers - -# set working directory for the user -WORKDIR /home/${container_user} - -ENV work_dir=/home/${container_user} - -ARG loader_path=${work_dir}/additional_jars - -RUN mkdir -p ${loader_path} - -ENV loader_path_env=${loader_path} - -ENV current_module_env=authentication-otp-service - -ADD configure_start.sh configure_start.sh - -RUN chmod +x configure_start.sh - -ADD target/${current_module_env}-*.jar ${current_module_env}.jar - -EXPOSE 8092 - -EXPOSE 9010 - -# change permissions of file inside working dir -RUN chown -R ${container_user}:${container_user} /home/${container_user} - -# select container user for all tasks -USER ${container_user_uid}:${container_user_gid} - -ENTRYPOINT [ "./configure_start.sh" ] - -CMD if [ "$is_glowroot_env" = "present" ]; then \ - wget -q --show-progress "${artifactory_url_env}"/artifactory/libs-release-local/io/mosip/testing/glowroot.zip ; \ - unzip glowroot.zip ; \ - rm -rf glowroot.zip ; \ - sed -i "s//${current_module_env}/g" glowroot/glowroot.properties ; \ - wget -q --show-progress "${iam_adapter_url_env}" -O "${loader_path_env}"/kernel-auth-adapter.jar; \ - java -jar -Djava.security.debug=sunpkcs11 -javaagent:glowroot/glowroot.jar -Dspring.cloud.config.label="${spring_config_label_env}" -Dspring.profiles.active="${active_profile_env}" -Dspring.cloud.config.uri="${spring_config_url_env}" -Dloader.path="${loader_path_env}" ${current_module_env}.jar ; \ - else \ - wget -q --show-progress "${iam_adapter_url_env}" -O "${loader_path_env}"/kernel-auth-adapter.jar; \ - java -jar -Djava.security.debug=sunpkcs11 -Dspring.cloud.config.label="${spring_config_label_env}" -Dspring.profiles.active="${active_profile_env}" -Dspring.cloud.config.uri="${spring_config_url_env}" -Dloader.path="${loader_path_env}" ${current_module_env}.jar ; \ - fi - -#Sample docker run command: +FROM openjdk:11 + +ARG SOURCE +ARG COMMIT_HASH +ARG COMMIT_ID +ARG BUILD_TIME +LABEL source=${SOURCE} +LABEL commit_hash=${COMMIT_HASH} +LABEL commit_id=${COMMIT_ID} +LABEL build_time=${BUILD_TIME} + +# can be passed during Docker build as build time environment for github branch to pickup configuration from. +ARG spring_config_label + +# can be passed during Docker build as build time environment for spring profiles active +ARG active_profile + +# can be passed during Docker build as build time environment for config server URL +ARG spring_config_url + +# can be passed during Docker build as build time environment for hsm client zip file path +#ARG client_zip_path +ARG hsm_client_zip_path + +# can be passed during Docker build as build time environment for glowroot +ARG is_glowroot + +# can be passed during Docker build as build time environment for artifactory URL +ARG artifactory_url + +# environment variable to pass active profile such as DEV, QA etc at docker runtime +ENV active_profile_env=${active_profile} + +# environment variable to pass github branch to pickup configuration from, at docker runtime +ENV spring_config_label_env=${spring_config_label} + +# environment variable to pass spring configuration url, at docker runtime +ENV spring_config_url_env=${spring_config_url} + +# environment variable to pass glowroot, at docker runtime +ENV is_glowroot_env=${is_glowroot} + +# environment variable to pass artifactory url, at docker runtime +ENV artifactory_url_env=${artifactory_url} + +# environment variable to pass iam_adapter url, at docker runtime +ENV iam_adapter_url_env=${iam_adapter_url} + +# environment variable to pass hsm client zip file path, at docker runtime +#ENV zip_file_path=${client_zip_path} +ENV hsm_zip_file_path=${hsm_client_zip_path} + +#ENV work_dir_env=/ + +# can be passed during Docker build as build time environment for github branch to pickup configuration from. +ARG container_user=mosip + +# can be passed during Docker build as build time environment for github branch to pickup configuration from. +ARG container_user_group=mosip + +# can be passed during Docker build as build time environment for github branch to pickup configuration from. +ARG container_user_uid=1001 + +# can be passed during Docker build as build time environment for github branch to pickup configuration from. +ARG container_user_gid=1001 + +ARG hsm_local_dir=hsm-client + +ENV hsm_local_dir_name=${hsm_local_dir} + +# install packages and create user +RUN apt-get -y update \ +&& apt-get install -y unzip sudo \ +&& groupadd -g ${container_user_gid} ${container_user_group} \ +&& useradd -u ${container_user_uid} -g ${container_user_group} -s /bin/sh -m ${container_user} \ +&& adduser ${container_user} sudo \ +&& echo "%sudo ALL=(ALL) NOPASSWD:/home/${container_user}/${hsm_local_dir}/install.sh" >> /etc/sudoers + +# set working directory for the user +WORKDIR /home/${container_user} + +ENV work_dir=/home/${container_user} + +ARG loader_path=${work_dir}/additional_jars + +RUN mkdir -p ${loader_path} + +ENV loader_path_env=${loader_path} + +ENV current_module_env=authentication-otp-service + +ADD configure_start.sh configure_start.sh + +RUN chmod +x configure_start.sh + +ADD target/${current_module_env}-*.jar ${current_module_env}.jar + +EXPOSE 8092 + +EXPOSE 9010 + +# change permissions of file inside working dir +RUN chown -R ${container_user}:${container_user} /home/${container_user} + +# select container user for all tasks +USER ${container_user_uid}:${container_user_gid} + +ENTRYPOINT [ "./configure_start.sh" ] + +CMD if [ "$is_glowroot_env" = "present" ]; then \ + wget -q "${artifactory_url_env}"/artifactory/libs-release-local/io/mosip/testing/glowroot.zip ; \ + unzip glowroot.zip ; \ + rm -rf glowroot.zip ; \ + sed -i "s//${current_module_env}/g" glowroot/glowroot.properties ; \ + wget -q "${iam_adapter_url_env}" -O "${loader_path_env}"/kernel-auth-adapter.jar; \ + java -jar -Djava.security.debug=sunpkcs11 -javaagent:glowroot/glowroot.jar -Dspring.cloud.config.label="${spring_config_label_env}" -Dspring.profiles.active="${active_profile_env}" -Dspring.cloud.config.uri="${spring_config_url_env}" -Dloader.path="${loader_path_env}" ${current_module_env}.jar ; \ + else \ + wget -q "${iam_adapter_url_env}" -O "${loader_path_env}"/kernel-auth-adapter.jar; \ + java -jar -Djava.security.debug=sunpkcs11 -Dspring.cloud.config.label="${spring_config_label_env}" -Dspring.profiles.active="${active_profile_env}" -Dspring.cloud.config.uri="${spring_config_url_env}" -Dloader.path="${loader_path_env}" ${current_module_env}.jar ; \ + fi + +#Sample docker run command: # sudo docker run --rm -it -e artifactory_url_env="http://artifactory" -e spring_config_label_env="1.0.9" -e active_profile_env="dev" -e spring_config_url_env="http://config-server/config" -e PKCS11_PROXY_SOCKET=tcp://softhsm-ida:5666 -p 8092:8092 authentication-otp-service:1.0.9 \ No newline at end of file diff --git a/authentication/authentication-otp-service/src/main/java/io/mosip/authentication/otp/service/OtpApplication.java b/authentication/authentication-otp-service/src/main/java/io/mosip/authentication/otp/service/OtpApplication.java index 1c80b631a5a..89e81a1a3bc 100644 --- a/authentication/authentication-otp-service/src/main/java/io/mosip/authentication/otp/service/OtpApplication.java +++ b/authentication/authentication-otp-service/src/main/java/io/mosip/authentication/otp/service/OtpApplication.java @@ -1,125 +1,127 @@ -package io.mosip.authentication.otp.service; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.FilterType; -import org.springframework.context.annotation.Import; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; - -import io.mosip.authentication.common.manager.IdAuthFraudAnalysisEventManager; -import io.mosip.authentication.common.service.builder.MatchInputBuilder; -import io.mosip.authentication.common.service.cache.MasterDataCache; -import io.mosip.authentication.common.service.cache.MasterDataCacheInitializer; -import io.mosip.authentication.common.service.config.IDAMappingConfig; -import io.mosip.authentication.common.service.config.LangComparatorConfig; -import io.mosip.authentication.common.service.config.OpenApiProperties; -import io.mosip.authentication.common.service.config.SwaggerConfig; -import io.mosip.authentication.common.service.exception.IdAuthExceptionHandler; -import io.mosip.authentication.common.service.factory.AuditRequestFactory; -import io.mosip.authentication.common.service.factory.RestRequestFactory; -import io.mosip.authentication.common.service.helper.AuditHelper; -import io.mosip.authentication.common.service.helper.AuthTransactionHelper; -import io.mosip.authentication.common.service.helper.ExternalRestHelperConfig; -import io.mosip.authentication.common.service.helper.IdInfoHelper; -import io.mosip.authentication.common.service.helper.WebSubHelper; -import io.mosip.authentication.common.service.impl.AuthContextClazzRefProvider; -import io.mosip.authentication.common.service.impl.AuthtypeStatusImpl; -import io.mosip.authentication.common.service.impl.IdInfoFetcherImpl; -import io.mosip.authentication.common.service.impl.IdServiceImpl; -import io.mosip.authentication.common.service.impl.KeyBindedTokenAuthServiceImpl; -import io.mosip.authentication.common.service.impl.OTPAuthServiceImpl; -import io.mosip.authentication.common.service.impl.OTPServiceImpl; -import io.mosip.authentication.common.service.impl.hotlist.HotlistServiceImpl; -import io.mosip.authentication.common.service.impl.masterdata.MasterDataCacheUpdateServiceImpl; -import io.mosip.authentication.common.service.impl.notification.NotificationServiceImpl; -import io.mosip.authentication.common.service.impl.patrner.PartnerCACertEventServiceImpl; -import io.mosip.authentication.common.service.impl.patrner.PartnerServiceImpl; -import io.mosip.authentication.common.service.integration.IdTemplateManager; -import io.mosip.authentication.common.service.integration.KeyManager; -import io.mosip.authentication.common.service.integration.MasterDataManager; -import io.mosip.authentication.common.service.integration.NotificationManager; -import io.mosip.authentication.common.service.integration.OTPManager; -import io.mosip.authentication.common.service.integration.PartnerServiceManager; -import io.mosip.authentication.common.service.integration.TokenIdManager; -import io.mosip.authentication.common.service.transaction.manager.IdAuthSecurityManager; -import io.mosip.authentication.common.service.util.EnvUtil; -import io.mosip.authentication.common.service.util.IdaRequestResponsConsumerUtil; -import io.mosip.authentication.common.service.util.KeyBindedTokenMatcherUtil; -import io.mosip.authentication.common.service.validator.OTPRequestValidator; -import io.mosip.authentication.common.service.websub.IdAuthWebSubInitializer; -import io.mosip.authentication.common.service.websub.impl.AuthAnonymousEventPublisher; -import io.mosip.authentication.common.service.websub.impl.AuthTransactionStatusEventPublisher; -import io.mosip.authentication.common.service.websub.impl.IdAuthFraudAnalysisEventPublisher; -import io.mosip.authentication.common.service.websub.impl.MasterDataUpdateEventInitializer; -import io.mosip.authentication.common.service.websub.impl.PartnerCACertEventInitializer; -import io.mosip.authentication.common.service.websub.impl.PartnerServiceEventsInitializer; -import io.mosip.authentication.core.util.IdTypeUtil; -import io.mosip.authentication.core.util.IdValidationUtil; -import io.mosip.kernel.cbeffutil.impl.CbeffImpl; -import io.mosip.kernel.core.retry.RetryAspect; -import io.mosip.kernel.core.retry.RetryConfig; -import io.mosip.kernel.core.retry.RetryListenerImpl; -import io.mosip.kernel.core.util.RetryUtil; -import io.mosip.kernel.crypto.jce.core.CryptoCore; -import io.mosip.kernel.cryptomanager.service.impl.CryptomanagerServiceImpl; -import io.mosip.kernel.cryptomanager.util.CryptomanagerUtils; -import io.mosip.kernel.dataaccess.hibernate.config.HibernateDaoConfig; -import io.mosip.kernel.keygenerator.bouncycastle.KeyGenerator; -import io.mosip.kernel.keymanager.hsm.impl.KeyStoreImpl; -import io.mosip.kernel.keymanagerservice.helper.KeymanagerDBHelper; -import io.mosip.kernel.keymanagerservice.helper.SessionKeyDecrytorHelper; -import io.mosip.kernel.keymanagerservice.service.impl.KeymanagerServiceImpl; -import io.mosip.kernel.keymanagerservice.util.KeymanagerUtil; -import io.mosip.kernel.partnercertservice.helper.PartnerCertManagerDBHelper; -import io.mosip.kernel.partnercertservice.service.impl.PartnerCertificateManagerServiceImpl; -import io.mosip.kernel.pinvalidator.impl.PinValidatorImpl; -import io.mosip.kernel.signature.service.impl.SignatureServiceImpl; -import io.mosip.kernel.templatemanager.velocity.builder.TemplateManagerBuilderImpl; -import io.mosip.kernel.tokenidgenerator.generator.TokenIDGenerator; -import io.mosip.kernel.tokenidgenerator.service.impl.TokenIDGeneratorServiceImpl; -import io.mosip.kernel.zkcryptoservice.service.impl.ZKCryptoManagerServiceImpl; - -/** - * Spring-boot class for ID Authentication Application. - * - * @author Dinesh Karuppiah - */ -@SpringBootApplication(exclude = { HibernateDaoConfig.class }) -@Import(value = {IdValidationUtil.class, IDAMappingConfig.class, KeyBindedTokenAuthServiceImpl.class, - KeyManager.class, AuthContextClazzRefProvider.class, - RestRequestFactory.class, IdInfoFetcherImpl.class, OTPManager.class, MasterDataManager.class, MatchInputBuilder.class, - NotificationManager.class, NotificationServiceImpl.class, IdTemplateManager.class, TemplateManagerBuilderImpl.class, - IdAuthExceptionHandler.class, OTPAuthServiceImpl.class, IdInfoHelper.class, CbeffImpl.class, - IdServiceImpl.class, AuditRequestFactory.class, TokenIdManager.class, - SwaggerConfig.class, AuditHelper.class, IdAuthExceptionHandler.class, PinValidatorImpl.class, - OTPServiceImpl.class, OTPRequestValidator.class, IdAuthSecurityManager.class, AuthtypeStatusImpl.class, CryptoCore.class, - PartnerServiceImpl.class, CryptomanagerServiceImpl.class, KeyGenerator.class, CryptomanagerUtils.class, - KeymanagerServiceImpl.class, KeymanagerUtil.class, TokenIDGeneratorServiceImpl.class, TokenIDGenerator.class, - PartnerServiceManager.class, SignatureServiceImpl.class, KeyStoreImpl.class, KeymanagerDBHelper.class, - ZKCryptoManagerServiceImpl.class, IdTypeUtil.class, MasterDataCache.class, MasterDataCacheInitializer.class, - PartnerCertificateManagerServiceImpl.class, PartnerCertManagerDBHelper.class, WebSubHelper.class, - PartnerServiceEventsInitializer.class, RetryConfig.class, RetryUtil.class, - RetryListenerImpl.class, RetryAspect.class, AuthTransactionHelper.class, HotlistServiceImpl.class, - AuthTransactionStatusEventPublisher.class, MasterDataCacheUpdateServiceImpl.class, - MasterDataUpdateEventInitializer.class, IdAuthFraudAnalysisEventManager.class, IdAuthFraudAnalysisEventPublisher.class, - LangComparatorConfig.class, OpenApiProperties.class, SessionKeyDecrytorHelper.class, ExternalRestHelperConfig.class, IdaRequestResponsConsumerUtil.class, - PartnerCACertEventServiceImpl.class, PartnerCACertEventInitializer.class, - IdAuthWebSubInitializer.class, AuthAnonymousEventPublisher.class, EnvUtil.class, KeyBindedTokenMatcherUtil.class }) -@ComponentScan(basePackages = { "io.mosip.authentication.otp.service.*", - "io.mosip.kernel.core.logger.config", "${mosip.auth.adapter.impl.basepackage}" }, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = { - "io.mosip.idrepository.core.config.IdRepoDataSourceConfig.*" })) -@EnableJpaRepositories(basePackages = { "io.mosip.authentication.common.service.repository.*", - "io.mosip.kernel.keymanagerservice.repository.*" }) -public class OtpApplication { - - /** - * The main method. - * - * @param args the arguments - */ - public static void main(String[] args) { - SpringApplication.run(OtpApplication.class, args); - } - -} \ No newline at end of file +package io.mosip.authentication.otp.service; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import org.springframework.context.annotation.Import; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +import io.mosip.authentication.common.manager.IdAuthFraudAnalysisEventManager; +import io.mosip.authentication.common.service.builder.MatchInputBuilder; +import io.mosip.authentication.common.service.cache.MasterDataCache; +import io.mosip.authentication.common.service.cache.MasterDataCacheInitializer; +import io.mosip.authentication.common.service.config.IDAMappingConfig; +import io.mosip.authentication.common.service.config.LangComparatorConfig; +import io.mosip.authentication.common.service.config.OpenApiProperties; +import io.mosip.authentication.common.service.config.SwaggerConfig; +import io.mosip.authentication.common.service.exception.IdAuthExceptionHandler; +import io.mosip.authentication.common.service.factory.AuditRequestFactory; +import io.mosip.authentication.common.service.factory.RestRequestFactory; +import io.mosip.authentication.common.service.helper.AuditHelper; +import io.mosip.authentication.common.service.helper.AuthTransactionHelper; +import io.mosip.authentication.common.service.helper.ExternalRestHelperConfig; +import io.mosip.authentication.common.service.helper.IdInfoHelper; +import io.mosip.authentication.common.service.helper.WebSubHelper; +import io.mosip.authentication.common.service.impl.AuthContextClazzRefProvider; +import io.mosip.authentication.common.service.impl.AuthtypeStatusImpl; +import io.mosip.authentication.common.service.impl.IdInfoFetcherImpl; +import io.mosip.authentication.common.service.impl.IdServiceImpl; +import io.mosip.authentication.common.service.impl.KeyBindedTokenAuthServiceImpl; +import io.mosip.authentication.common.service.impl.OTPAuthServiceImpl; +import io.mosip.authentication.common.service.impl.OTPServiceImpl; +import io.mosip.authentication.common.service.impl.hotlist.HotlistServiceImpl; +import io.mosip.authentication.common.service.impl.masterdata.MasterDataCacheUpdateServiceImpl; +import io.mosip.authentication.common.service.impl.notification.NotificationServiceImpl; +import io.mosip.authentication.common.service.impl.patrner.PartnerCACertEventServiceImpl; +import io.mosip.authentication.common.service.impl.patrner.PartnerServiceImpl; +import io.mosip.authentication.common.service.integration.IdTemplateManager; +import io.mosip.authentication.common.service.integration.KeyManager; +import io.mosip.authentication.common.service.integration.MasterDataManager; +import io.mosip.authentication.common.service.integration.NotificationManager; +import io.mosip.authentication.common.service.integration.OTPManager; +import io.mosip.authentication.common.service.integration.PartnerServiceManager; +import io.mosip.authentication.common.service.integration.TokenIdManager; +import io.mosip.authentication.common.service.transaction.manager.IdAuthSecurityManager; +import io.mosip.authentication.common.service.util.EnvUtil; +import io.mosip.authentication.common.service.util.IdaRequestResponsConsumerUtil; +import io.mosip.authentication.common.service.util.KeyBindedTokenMatcherUtil; +import io.mosip.authentication.common.service.validator.OTPRequestValidator; +import io.mosip.authentication.common.service.websub.IdAuthWebSubInitializer; +import io.mosip.authentication.common.service.websub.impl.AuthAnonymousEventPublisher; +import io.mosip.authentication.common.service.websub.impl.AuthTransactionStatusEventPublisher; +import io.mosip.authentication.common.service.websub.impl.IdAuthFraudAnalysisEventPublisher; +import io.mosip.authentication.common.service.websub.impl.MasterDataUpdateEventInitializer; +import io.mosip.authentication.common.service.websub.impl.PartnerCACertEventInitializer; +import io.mosip.authentication.common.service.websub.impl.PartnerServiceEventsInitializer; +import io.mosip.authentication.core.util.IdTypeUtil; +import io.mosip.authentication.core.util.IdValidationUtil; +import io.mosip.kernel.cbeffutil.impl.CbeffImpl; +import io.mosip.kernel.core.retry.RetryAspect; +import io.mosip.kernel.core.retry.RetryConfig; +import io.mosip.kernel.core.retry.RetryListenerImpl; +import io.mosip.kernel.core.util.RetryUtil; +import io.mosip.kernel.crypto.jce.core.CryptoCore; +import io.mosip.kernel.cryptomanager.service.impl.CryptomanagerServiceImpl; +import io.mosip.kernel.cryptomanager.util.CryptomanagerUtils; +import io.mosip.kernel.dataaccess.hibernate.config.HibernateDaoConfig; +import io.mosip.kernel.keygenerator.bouncycastle.KeyGenerator; +import io.mosip.kernel.keymanager.hsm.health.HSMHealthCheck; +import io.mosip.kernel.keymanager.hsm.impl.KeyStoreImpl; +import io.mosip.kernel.keymanagerservice.helper.KeymanagerDBHelper; +import io.mosip.kernel.keymanagerservice.helper.PrivateKeyDecryptorHelper; +import io.mosip.kernel.keymanagerservice.helper.SessionKeyDecrytorHelper; +import io.mosip.kernel.keymanagerservice.service.impl.KeymanagerServiceImpl; +import io.mosip.kernel.keymanagerservice.util.KeymanagerUtil; +import io.mosip.kernel.partnercertservice.helper.PartnerCertManagerDBHelper; +import io.mosip.kernel.partnercertservice.service.impl.PartnerCertificateManagerServiceImpl; +import io.mosip.kernel.pinvalidator.impl.PinValidatorImpl; +import io.mosip.kernel.signature.service.impl.SignatureServiceImpl; +import io.mosip.kernel.templatemanager.velocity.builder.TemplateManagerBuilderImpl; +import io.mosip.kernel.tokenidgenerator.generator.TokenIDGenerator; +import io.mosip.kernel.tokenidgenerator.service.impl.TokenIDGeneratorServiceImpl; +import io.mosip.kernel.zkcryptoservice.service.impl.ZKCryptoManagerServiceImpl; + +/** + * Spring-boot class for ID Authentication Application. + * + * @author Dinesh Karuppiah + */ +@SpringBootApplication(exclude = { HibernateDaoConfig.class }) +@Import(value = {IdValidationUtil.class, IDAMappingConfig.class, KeyBindedTokenAuthServiceImpl.class, + KeyManager.class, AuthContextClazzRefProvider.class, + RestRequestFactory.class, IdInfoFetcherImpl.class, OTPManager.class, MasterDataManager.class, MatchInputBuilder.class, + NotificationManager.class, NotificationServiceImpl.class, IdTemplateManager.class, TemplateManagerBuilderImpl.class, + IdAuthExceptionHandler.class, OTPAuthServiceImpl.class, IdInfoHelper.class, CbeffImpl.class, + IdServiceImpl.class, AuditRequestFactory.class, TokenIdManager.class, + SwaggerConfig.class, AuditHelper.class, IdAuthExceptionHandler.class, PinValidatorImpl.class, + OTPServiceImpl.class, OTPRequestValidator.class, IdAuthSecurityManager.class, AuthtypeStatusImpl.class, CryptoCore.class, + PartnerServiceImpl.class, CryptomanagerServiceImpl.class, KeyGenerator.class, CryptomanagerUtils.class, + KeymanagerServiceImpl.class, KeymanagerUtil.class, TokenIDGeneratorServiceImpl.class, TokenIDGenerator.class, + PartnerServiceManager.class, SignatureServiceImpl.class, KeyStoreImpl.class, KeymanagerDBHelper.class, + ZKCryptoManagerServiceImpl.class, IdTypeUtil.class, MasterDataCache.class, MasterDataCacheInitializer.class, + PartnerCertificateManagerServiceImpl.class, PartnerCertManagerDBHelper.class, WebSubHelper.class, + PartnerServiceEventsInitializer.class, RetryConfig.class, RetryUtil.class, + RetryListenerImpl.class, RetryAspect.class, AuthTransactionHelper.class, HotlistServiceImpl.class, + AuthTransactionStatusEventPublisher.class, MasterDataCacheUpdateServiceImpl.class, + MasterDataUpdateEventInitializer.class, IdAuthFraudAnalysisEventManager.class, IdAuthFraudAnalysisEventPublisher.class, + LangComparatorConfig.class, OpenApiProperties.class, SessionKeyDecrytorHelper.class, ExternalRestHelperConfig.class, IdaRequestResponsConsumerUtil.class, + PartnerCACertEventServiceImpl.class, PartnerCACertEventInitializer.class, + IdAuthWebSubInitializer.class, AuthAnonymousEventPublisher.class, EnvUtil.class, KeyBindedTokenMatcherUtil.class, + HSMHealthCheck.class, PrivateKeyDecryptorHelper.class }) +@ComponentScan(basePackages = { "io.mosip.authentication.otp.service.*", + "io.mosip.kernel.core.logger.config", "${mosip.auth.adapter.impl.basepackage}" }, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = { + "io.mosip.idrepository.core.config.IdRepoDataSourceConfig.*" })) +@EnableJpaRepositories(basePackages = { "io.mosip.authentication.common.service.repository.*", + "io.mosip.kernel.keymanagerservice.repository.*" }) +public class OtpApplication { + + /** + * The main method. + * + * @param args the arguments + */ + public static void main(String[] args) { + SpringApplication.run(OtpApplication.class, args); + } +} diff --git a/authentication/authentication-service/Dockerfile b/authentication/authentication-service/Dockerfile index a599400a367..ab0a6b78234 100644 --- a/authentication/authentication-service/Dockerfile +++ b/authentication/authentication-service/Dockerfile @@ -1,145 +1,145 @@ -FROM openjdk:11 - -ARG SOURCE -ARG COMMIT_HASH -ARG COMMIT_ID -ARG BUILD_TIME -LABEL source=${SOURCE} -LABEL commit_hash=${COMMIT_HASH} -LABEL commit_id=${COMMIT_ID} -LABEL build_time=${BUILD_TIME} - -# can be passed during Docker build as build time environment for github branch to pickup configuration from. -ARG spring_config_label - -# can be passed during Docker build as build time environment for spring profiles active -ARG active_profile - -# can be passed during Docker build as build time environment for config server URL -ARG spring_config_url - -#ARG bio_sdk_folder=mock/0.9 -ARG biosdk_zip_path - -ARG demosdk_zip_path - -# can be passed during Docker build as build time environment for hsm client zip file path -#ARG client_zip_path -ARG hsm_client_zip_path - -# can be passed during Docker build as build time environment for glowroot -ARG is_glowroot - -# can be passed during Docker build as build time environment for artifactory URL -ARG artifactory_url - -# environment variable to pass active profile such as DEV, QA etc at docker runtime -ENV active_profile_env=${active_profile} - -# environment variable to pass github branch to pickup configuration from, at docker runtime -ENV spring_config_label_env=${spring_config_label} - -# environment variable to pass spring configuration url, at docker runtime -ENV spring_config_url_env=${spring_config_url} - -# environment variable to pass glowroot, at docker runtime -ENV is_glowroot_env=${is_glowroot} - -# environment variable to pass artifactory url, at docker runtime -ENV artifactory_url_env=${artifactory_url} - -# environment variable to pass iam_adapter url, at docker runtime -ENV iam_adapter_url_env=${iam_adapter_url} - -#ENV bio_sdk_folder_env=${bio_sdk_folder} -ENV biosdk_zip_file_path=${biosdk_zip_path} - -#ENV demo_sdk_folder_env=${demo_sdk_folder} -ENV demosdk_zip_file_path=${demosdk_zip_path} - -# environment variable to pass hsm client zip file path, at docker runtime -#ENV zip_file_path=${client_zip_path} -ENV hsm_zip_file_path=${hsm_client_zip_path} - -#ENV work_dir_env=/ - -# can be passed during Docker build as build time environment for github branch to pickup configuration from. -ARG container_user=mosip - -# can be passed during Docker build as build time environment for github branch to pickup configuration from. -ARG container_user_group=mosip - -# can be passed during Docker build as build time environment for github branch to pickup configuration from. -ARG container_user_uid=1001 - -# can be passed during Docker build as build time environment for github branch to pickup configuration from. -ARG container_user_gid=1001 - -ARG hsm_local_dir=hsm-client - -ENV hsm_local_dir_name=${hsm_local_dir} - -ARG biosdk_local_dir=biosdk-client - -ARG demosdk_local_dir=demosdk - -ENV biosdk_local_dir_name=${biosdk_local_dir} - -ENV demosdk_local_dir_name=${demosdk_local_dir} - -# install packages and create user -RUN apt-get -y update \ -&& apt-get install -y unzip sudo \ -&& groupadd -g ${container_user_gid} ${container_user_group} \ -&& useradd -u ${container_user_uid} -g ${container_user_group} -s /bin/sh -m ${container_user} \ -&& adduser ${container_user} sudo \ -&& echo "%sudo ALL=(ALL) NOPASSWD:/home/${container_user}/${hsm_local_dir}/install.sh" >> /etc/sudoers \ -&& echo "%sudo ALL=(ALL) NOPASSWD:/home/${container_user}/${biosdk_local_dir}/install.sh" >> /etc/sudoers - -# set working directory for the user -WORKDIR /home/${container_user} - -ENV work_dir=/home/${container_user} - -ARG loader_path=${work_dir}/additional_jars/ - -RUN mkdir -p ${loader_path} - -ENV loader_path_env=${loader_path} - -ENV current_module_env=authentication-service - -ADD configure_start.sh configure_start.sh - -RUN chmod +x configure_start.sh - -ADD target/${current_module_env}-*.jar ${current_module_env}.jar - -EXPOSE 8090 - -EXPOSE 9010 - -# change permissions of file inside working dir -RUN chown -R ${container_user}:${container_user} /home/${container_user} - -# select container user for all tasks -USER ${container_user_uid}:${container_user_gid} - -ENTRYPOINT [ "./configure_start.sh" ] - -CMD if [ "$is_glowroot_env" = "present" ]; then \ - wget -q --show-progress "${artifactory_url_env}"/artifactory/libs-release-local/io/mosip/authentication/authentication-ref-impl/authentication-childauthfilter-impl.jar -O "${loader_path_env}"/authentication-childauthfilter-impl.jar ; \ - wget -q --show-progress "${artifactory_url_env}"/artifactory/libs-release-local/io/mosip/testing/glowroot.zip ; \ - unzip glowroot.zip ; \ - rm -rf glowroot.zip ; \ - sed -i "s//${current_module_env}/g" glowroot/glowroot.properties ; \ - wget -q --show-progress "${iam_adapter_url_env}" -O "${loader_path_env}"/kernel-auth-adapter.jar; \ - java -jar -Djava.security.debug=sunpkcs11 -javaagent:glowroot/glowroot.jar -Dspring.cloud.config.label="${spring_config_label_env}" -Dspring.profiles.active="${active_profile_env}" -Dspring.cloud.config.uri="${spring_config_url_env}" -Dloader.path="${loader_path_env}" -Dfile.encoding="UTF-8" ${current_module_env}.jar ; \ - else \ - wget -q --show-progress "${artifactory_url_env}"/artifactory/libs-release-local/io/mosip/authentication/authentication-ref-impl/authentication-childauthfilter-impl.jar -O "${loader_path_env}"/authentication-childauthfilter-impl.jar ; \ - wget -q --show-progress "${iam_adapter_url_env}" -O "${loader_path_env}"/kernel-auth-adapter.jar; \ - java -jar -Djava.security.debug=sunpkcs11 -Dspring.cloud.config.label="${spring_config_label_env}" -Dspring.profiles.active="${active_profile_env}" -Dspring.cloud.config.uri="${spring_config_url_env}" -Dloader.path="${loader_path_env}" -Dfile.encoding="UTF-8" ${current_module_env}.jar ; \ - fi - -#Sample docker run command: +FROM openjdk:11 + +ARG SOURCE +ARG COMMIT_HASH +ARG COMMIT_ID +ARG BUILD_TIME +LABEL source=${SOURCE} +LABEL commit_hash=${COMMIT_HASH} +LABEL commit_id=${COMMIT_ID} +LABEL build_time=${BUILD_TIME} + +# can be passed during Docker build as build time environment for github branch to pickup configuration from. +ARG spring_config_label + +# can be passed during Docker build as build time environment for spring profiles active +ARG active_profile + +# can be passed during Docker build as build time environment for config server URL +ARG spring_config_url + +#ARG bio_sdk_folder=mock/0.9 +ARG biosdk_zip_path + +ARG demosdk_zip_path + +# can be passed during Docker build as build time environment for hsm client zip file path +#ARG client_zip_path +ARG hsm_client_zip_path + +# can be passed during Docker build as build time environment for glowroot +ARG is_glowroot + +# can be passed during Docker build as build time environment for artifactory URL +ARG artifactory_url + +# environment variable to pass active profile such as DEV, QA etc at docker runtime +ENV active_profile_env=${active_profile} + +# environment variable to pass github branch to pickup configuration from, at docker runtime +ENV spring_config_label_env=${spring_config_label} + +# environment variable to pass spring configuration url, at docker runtime +ENV spring_config_url_env=${spring_config_url} + +# environment variable to pass glowroot, at docker runtime +ENV is_glowroot_env=${is_glowroot} + +# environment variable to pass artifactory url, at docker runtime +ENV artifactory_url_env=${artifactory_url} + +# environment variable to pass iam_adapter url, at docker runtime +ENV iam_adapter_url_env=${iam_adapter_url} + +#ENV bio_sdk_folder_env=${bio_sdk_folder} +ENV biosdk_zip_file_path=${biosdk_zip_path} + +#ENV demo_sdk_folder_env=${demo_sdk_folder} +ENV demosdk_zip_file_path=${demosdk_zip_path} + +# environment variable to pass hsm client zip file path, at docker runtime +#ENV zip_file_path=${client_zip_path} +ENV hsm_zip_file_path=${hsm_client_zip_path} + +#ENV work_dir_env=/ + +# can be passed during Docker build as build time environment for github branch to pickup configuration from. +ARG container_user=mosip + +# can be passed during Docker build as build time environment for github branch to pickup configuration from. +ARG container_user_group=mosip + +# can be passed during Docker build as build time environment for github branch to pickup configuration from. +ARG container_user_uid=1001 + +# can be passed during Docker build as build time environment for github branch to pickup configuration from. +ARG container_user_gid=1001 + +ARG hsm_local_dir=hsm-client + +ENV hsm_local_dir_name=${hsm_local_dir} + +ARG biosdk_local_dir=biosdk-client + +ARG demosdk_local_dir=demosdk + +ENV biosdk_local_dir_name=${biosdk_local_dir} + +ENV demosdk_local_dir_name=${demosdk_local_dir} + +# install packages and create user +RUN apt-get -y update \ +&& apt-get install -y unzip sudo \ +&& groupadd -g ${container_user_gid} ${container_user_group} \ +&& useradd -u ${container_user_uid} -g ${container_user_group} -s /bin/sh -m ${container_user} \ +&& adduser ${container_user} sudo \ +&& echo "%sudo ALL=(ALL) NOPASSWD:/home/${container_user}/${hsm_local_dir}/install.sh" >> /etc/sudoers \ +&& echo "%sudo ALL=(ALL) NOPASSWD:/home/${container_user}/${biosdk_local_dir}/install.sh" >> /etc/sudoers + +# set working directory for the user +WORKDIR /home/${container_user} + +ENV work_dir=/home/${container_user} + +ARG loader_path=${work_dir}/additional_jars/ + +RUN mkdir -p ${loader_path} + +ENV loader_path_env=${loader_path} + +ENV current_module_env=authentication-service + +ADD configure_start.sh configure_start.sh + +RUN chmod +x configure_start.sh + +ADD target/${current_module_env}-*.jar ${current_module_env}.jar + +EXPOSE 8090 + +EXPOSE 9010 + +# change permissions of file inside working dir +RUN chown -R ${container_user}:${container_user} /home/${container_user} + +# select container user for all tasks +USER ${container_user_uid}:${container_user_gid} + +ENTRYPOINT [ "./configure_start.sh" ] + +CMD if [ "$is_glowroot_env" = "present" ]; then \ + wget -q "${artifactory_url_env}"/artifactory/libs-release-local/io/mosip/authentication/authentication-ref-impl/authentication-childauthfilter-impl.jar -O "${loader_path_env}"/authentication-childauthfilter-impl.jar ; \ + wget -q "${artifactory_url_env}"/artifactory/libs-release-local/io/mosip/testing/glowroot.zip ; \ + unzip glowroot.zip ; \ + rm -rf glowroot.zip ; \ + sed -i "s//${current_module_env}/g" glowroot/glowroot.properties ; \ + wget -q "${iam_adapter_url_env}" -O "${loader_path_env}"/kernel-auth-adapter.jar; \ + java -jar -Djava.security.debug=sunpkcs11 -javaagent:glowroot/glowroot.jar -Dspring.cloud.config.label="${spring_config_label_env}" -Dspring.profiles.active="${active_profile_env}" -Dspring.cloud.config.uri="${spring_config_url_env}" -Dloader.path="${loader_path_env}" -Dfile.encoding="UTF-8" ${current_module_env}.jar ; \ + else \ + wget -q "${artifactory_url_env}"/artifactory/libs-release-local/io/mosip/authentication/authentication-ref-impl/authentication-childauthfilter-impl.jar -O "${loader_path_env}"/authentication-childauthfilter-impl.jar ; \ + wget -q "${iam_adapter_url_env}" -O "${loader_path_env}"/kernel-auth-adapter.jar; \ + java -jar -Djava.security.debug=sunpkcs11 -Dspring.cloud.config.label="${spring_config_label_env}" -Dspring.profiles.active="${active_profile_env}" -Dspring.cloud.config.uri="${spring_config_url_env}" -Dloader.path="${loader_path_env}" -Dfile.encoding="UTF-8" ${current_module_env}.jar ; \ + fi + +#Sample docker run command: # sudo docker run --rm -it -e artifactory_url_env="http://artifactory" -e spring_config_label_env="1.0.9" -e active_profile_env="dev" -e spring_config_url_env="http://config-server/config" -e PKCS11_PROXY_SOCKET=tcp://softhsm-ida:5666 -p 8090:8090 authentication-service:1.0.9 \ No newline at end of file diff --git a/authentication/authentication-service/pom.xml b/authentication/authentication-service/pom.xml index 93c76b6903c..eeb3cee069f 100644 --- a/authentication/authentication-service/pom.xml +++ b/authentication/authentication-service/pom.xml @@ -210,6 +210,11 @@ opencv 4.5.3-4 + + info.weboftrust + ld-signatures-java + 1.0.0 + diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/IdAuthenticationApplication.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/IdAuthenticationApplication.java index 4a80ce98ed4..1f54f60bdec 100644 --- a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/IdAuthenticationApplication.java +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/IdAuthenticationApplication.java @@ -1,5 +1,6 @@ package io.mosip.authentication.service; +import io.mosip.authentication.common.service.util.KeyBindedTokenMatcherUtil; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; @@ -22,6 +23,7 @@ import io.mosip.authentication.common.service.helper.AuthTransactionHelper; import io.mosip.authentication.common.service.helper.ExternalRestHelperConfig; import io.mosip.authentication.common.service.helper.IdInfoHelper; +import io.mosip.authentication.common.service.helper.TokenValidationHelper; import io.mosip.authentication.common.service.helper.WebSubHelper; import io.mosip.authentication.common.service.impl.AuthAnonymousProfileServiceImpl; import io.mosip.authentication.common.service.impl.AuthContextClazzRefProvider; @@ -30,8 +32,8 @@ import io.mosip.authentication.common.service.impl.DemoAuthServiceImpl; import io.mosip.authentication.common.service.impl.IdInfoFetcherImpl; import io.mosip.authentication.common.service.impl.IdServiceImpl; -import io.mosip.authentication.common.service.impl.KeyBindedTokenAuthServiceImpl; import io.mosip.authentication.common.service.impl.OTPAuthServiceImpl; +import io.mosip.authentication.common.service.impl.KeyBindedTokenAuthServiceImpl; import io.mosip.authentication.common.service.impl.hotlist.HotlistServiceImpl; import io.mosip.authentication.common.service.impl.masterdata.MasterDataCacheUpdateServiceImpl; import io.mosip.authentication.common.service.impl.notification.NotificationServiceImpl; @@ -48,7 +50,6 @@ import io.mosip.authentication.common.service.util.BioMatcherUtil; import io.mosip.authentication.common.service.util.EnvUtil; import io.mosip.authentication.common.service.util.IdaRequestResponsConsumerUtil; -import io.mosip.authentication.common.service.util.KeyBindedTokenMatcherUtil; import io.mosip.authentication.common.service.validator.AuthFiltersValidator; import io.mosip.authentication.common.service.validator.AuthRequestValidator; import io.mosip.authentication.common.service.websub.IdAuthWebSubInitializer; @@ -62,6 +63,7 @@ import io.mosip.authentication.core.util.DemoNormalizer; import io.mosip.authentication.core.util.IdTypeUtil; import io.mosip.authentication.core.util.IdValidationUtil; +import io.mosip.authentication.service.kyc.util.VCSchemaProviderUtil; import io.mosip.kernel.biosdk.provider.factory.BioAPIFactory; import io.mosip.kernel.biosdk.provider.impl.BioProviderImpl_V_0_8; import io.mosip.kernel.biosdk.provider.impl.BioProviderImpl_V_0_9; @@ -77,6 +79,7 @@ import io.mosip.kernel.keygenerator.bouncycastle.KeyGenerator; import io.mosip.kernel.keymanager.hsm.impl.KeyStoreImpl; import io.mosip.kernel.keymanagerservice.helper.KeymanagerDBHelper; +import io.mosip.kernel.keymanagerservice.helper.PrivateKeyDecryptorHelper; import io.mosip.kernel.keymanagerservice.helper.SessionKeyDecrytorHelper; import io.mosip.kernel.keymanagerservice.service.impl.KeymanagerServiceImpl; import io.mosip.kernel.keymanagerservice.util.KeymanagerUtil; @@ -88,6 +91,8 @@ import io.mosip.kernel.tokenidgenerator.generator.TokenIDGenerator; import io.mosip.kernel.tokenidgenerator.service.impl.TokenIDGeneratorServiceImpl; import io.mosip.kernel.zkcryptoservice.service.impl.ZKCryptoManagerServiceImpl; +import io.mosip.kernel.keymanager.hsm.health.HSMHealthCheck; + /** * Spring-boot class for ID Authentication Application. @@ -116,7 +121,8 @@ MasterDataUpdateEventInitializer.class, DemoNormalizer.class, DemoMatcherUtil.class, IdAuthFraudAnalysisEventManager.class, IdAuthFraudAnalysisEventPublisher.class, AuthFiltersValidator.class, AuthAnonymousProfileServiceImpl.class, AuthAnonymousEventPublisher.class, SessionKeyDecrytorHelper.class, ExternalRestHelperConfig.class, IdaRequestResponsConsumerUtil.class, - PartnerCACertEventServiceImpl.class, PartnerCACertEventInitializer.class, EnvUtil.class, KeyBindedTokenMatcherUtil.class }) + PartnerCACertEventServiceImpl.class, PartnerCACertEventInitializer.class, EnvUtil.class, KeyBindedTokenMatcherUtil.class, + HSMHealthCheck.class, TokenValidationHelper.class, VCSchemaProviderUtil.class, PrivateKeyDecryptorHelper.class }) @ComponentScan(basePackages = { "io.mosip.authentication.service.*", "io.mosip.kernel.core.logger.config", "io.mosip.authentication.common.service.config", "${mosip.auth.adapter.impl.basepackage}" }, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = { "io.mosip.idrepository.core.config.IdRepoDataSourceConfig.*" })) @@ -133,4 +139,4 @@ public static void main(String[] args) { SpringApplication.run(IdAuthenticationApplication.class, args); } -} \ No newline at end of file +} diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/config/KycFilterConfig.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/config/KycFilterConfig.java index d4066164795..3e02f3c9b58 100644 --- a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/config/KycFilterConfig.java +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/config/KycFilterConfig.java @@ -8,6 +8,7 @@ import io.mosip.authentication.service.kyc.filter.KycAuthFilter; import io.mosip.authentication.service.kyc.filter.KycAuthenticationFilter; import io.mosip.authentication.service.kyc.filter.KycExchangeFilter; +import io.mosip.authentication.service.kyc.filter.VciExchangeFilter; /** * The configuration for adding filters. @@ -68,4 +69,17 @@ public FilterRegistrationBean getKeyBindingFilter() { registrationBean.addUrlPatterns("/identity-key-binding/*"); return registrationBean; } + + /** + * Gets the VCI Exchange filter. + * + * @return the VCI Exchange filter + */ + @Bean + public FilterRegistrationBean getVciExchangeFilter() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(new VciExchangeFilter()); + registrationBean.addUrlPatterns("/vci-exchange/*"); + return registrationBean; + } } diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/controller/IdentityWalletBindingController.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/controller/IdentityWalletBindingController.java index 987da263877..4cb61d879fc 100644 --- a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/controller/IdentityWalletBindingController.java +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/controller/IdentityWalletBindingController.java @@ -21,6 +21,7 @@ import io.mosip.authentication.common.service.helper.AuditHelper; import io.mosip.authentication.common.service.helper.AuthTransactionHelper; import io.mosip.authentication.common.service.util.IdaRequestResponsConsumerUtil; +import io.mosip.authentication.core.constant.AuditEvents; import io.mosip.authentication.core.constant.IdAuthCommonConstants; import io.mosip.authentication.core.constant.IdAuthenticationErrorConstants; import io.mosip.authentication.core.dto.ObjectWithMetadata; @@ -107,7 +108,7 @@ private void initKeyBindingAuthRequestBinder(WebDataBinder binder) { * @throws IdAuthenticationAppException the id authentication app exception * @throws IdAuthenticationDaoException the id authentication dao exception */ - @PostMapping(path = "/identity-key-binding/delegated/{IdP-LK}/{Auth-Partner-ID}/{API-Key}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @PostMapping(path = "/identity-key-binding/delegated/{IdP-LK}/{Auth-Partner-ID}/{OIDC-Client-Id}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Identity Key Binding Request", description = "to authenticate and bind key with the identity", tags = { "identity-wallet-binding-controller" }) @SecurityRequirement(name = "Authorization") @Parameter(in = ParameterIn.HEADER, name = "signature") @@ -118,8 +119,10 @@ private void initKeyBindingAuthRequestBinder(WebDataBinder binder) { @ApiResponse(responseCode = "403", description = "Forbidden" ,content = @Content(schema = @Schema(hidden = true))), @ApiResponse(responseCode = "404", description = "Not Found" ,content = @Content(schema = @Schema(hidden = true)))}) public IdentityKeyBindingResponseDto processIdKeyBinding(@Validated @RequestBody IdentityKeyBindingRequestDTO identityKeyBindingRequestDTO, - @ApiIgnore Errors errors, @PathVariable("IdP-LK") String mispLK,@PathVariable("Auth-Partner-ID") String partnerId, - @PathVariable("API-Key") String partnerApiKey, HttpServletRequest request) + @ApiIgnore Errors errors, @PathVariable("IdP-LK") String mispLK, + @PathVariable("Auth-Partner-ID") String partnerId, + @PathVariable("OIDC-Client-Id") String oidcClientId, + HttpServletRequest request) throws IdAuthenticationBusinessException, IdAuthenticationAppException, IdAuthenticationDaoException { if(request instanceof ObjectWithMetadata) { ObjectWithMetadata requestWrapperWithMetadata = (ObjectWithMetadata) request; @@ -136,7 +139,7 @@ public IdentityKeyBindingResponseDto processIdKeyBinding(@Validated @RequestBody DataValidationUtil.validate(errors); AuthResponseDTO authResponseDTO = keyIdentityFacade.authenticateIndividual(identityKeyBindingRequestDTO, partnerId, - partnerApiKey, requestWrapperWithMetadata); + oidcClientId, requestWrapperWithMetadata); IdentityKeyBindingResponseDto keyBindingResponseDto = new IdentityKeyBindingResponseDto(); Map metadata = requestWrapperWithMetadata.getMetadata(); @@ -145,12 +148,14 @@ public IdentityKeyBindingResponseDto processIdKeyBinding(@Validated @RequestBody metadata.get(IdAuthCommonConstants.IDENTITY_DATA) != null && metadata.get(IdAuthCommonConstants.IDENTITY_INFO) != null) { keyBindingResponseDto = keyIdentityFacade.processIdentityKeyBinding(identityKeyBindingRequestDTO, authResponseDTO, - partnerId, partnerApiKey, metadata); + partnerId, oidcClientId, metadata); } return keyBindingResponseDto; } catch (IDDataValidationException e) { mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "processIdKeyBinding", e.getErrorTexts().isEmpty() ? "" : e.getErrorText()); + + auditHelper.auditExceptionForAuthRequestedModules(AuditEvents.KEY_BINDIN_REQUEST_RESPONSE, identityKeyBindingRequestDTO, e); IdaRequestResponsConsumerUtil.setIdVersionToObjectWithMetadata(requestWrapperWithMetadata, e); if(identityKeyBindingRequestDTO.getTransactionID() == null) identityKeyBindingRequestDTO.setTransactionID(IdAuthCommonConstants.NO_TRANSACTION_ID); @@ -159,6 +164,8 @@ public IdentityKeyBindingResponseDto processIdKeyBinding(@Validated @RequestBody } catch (IdAuthenticationBusinessException e) { mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "processIdKeyBinding", e.getErrorTexts().isEmpty() ? "" : e.getErrorText()); + + auditHelper.auditExceptionForAuthRequestedModules(AuditEvents.KEY_BINDIN_REQUEST_RESPONSE, identityKeyBindingRequestDTO, e); authTransactionHelper.setAuthTransactionEntityMetadata(e, authTxnBuilder, requestWrapperWithMetadata); authTransactionHelper.setAuthTransactionEntityMetadata(requestWrapperWithMetadata, authTxnBuilder); IdaRequestResponsConsumerUtil.setIdVersionToObjectWithMetadata(requestWrapperWithMetadata, e); diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/controller/VCIController.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/controller/VCIController.java new file mode 100644 index 00000000000..affef774a7f --- /dev/null +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/controller/VCIController.java @@ -0,0 +1,165 @@ +package io.mosip.authentication.service.kyc.controller; + +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.validation.Errors; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import io.mosip.authentication.common.service.builder.AuthTransactionBuilder; +import io.mosip.authentication.common.service.helper.AuthTransactionHelper; +import io.mosip.authentication.common.service.util.IdaRequestResponsConsumerUtil; +import io.mosip.authentication.core.constant.IdAuthCommonConstants; +import io.mosip.authentication.core.constant.IdAuthenticationErrorConstants; +import io.mosip.authentication.core.dto.ObjectWithMetadata; +import io.mosip.authentication.core.exception.IDDataValidationException; +import io.mosip.authentication.core.exception.IdAuthenticationAppException; +import io.mosip.authentication.core.exception.IdAuthenticationBusinessException; +import io.mosip.authentication.core.exception.IdAuthenticationDaoException; +import io.mosip.authentication.core.indauth.dto.VciExchangeRequestDTO; +import io.mosip.authentication.core.indauth.dto.VciExchangeResponseDTO; +import io.mosip.authentication.core.logger.IdaLogger; +import io.mosip.authentication.core.partner.dto.PartnerDTO; +import io.mosip.authentication.core.spi.indauth.facade.VciFacade; +import io.mosip.authentication.core.spi.partner.service.PartnerService; +import io.mosip.authentication.core.util.DataValidationUtil; +import io.mosip.authentication.core.util.IdTypeUtil; +import io.mosip.authentication.service.kyc.validator.VciExchangeRequestValidator; +import io.mosip.kernel.core.logger.spi.Logger; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn; +import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.security.SecurityScheme; +import io.swagger.v3.oas.annotations.tags.Tag; +import springfox.documentation.annotations.ApiIgnore; + +/** + * The {@code VCIController} used to validate the issued authentication + * token and issue verifiable credentials after successful validation. + * + * @author Mahammed Taheer + */ +@RestController +@Tag(name = "vci-controller", description = "Verifiable Credential Issuance Controller") +@SecurityScheme(in = SecuritySchemeIn.HEADER, scheme = "basic", type = SecuritySchemeType.APIKEY, name = "Authorization") +public class VCIController { + + /** The mosipLogger. */ + private Logger mosipLogger = IdaLogger.getLogger(IdentityWalletBindingController.class); + + /** The vci facade. */ + @Autowired + private VciFacade vciFacade; + + @Autowired + private IdTypeUtil idTypeUtil; + + @Autowired + private AuthTransactionHelper authTransactionHelper; + + @Autowired + private PartnerService partnerService; + + /** The KycExchangeRequestValidator */ + @Autowired + private VciExchangeRequestValidator vciExchangeRequestValidator; + + /** + * + * @param binder the binder + */ + @InitBinder("vciExchangeRequestDTO") + private void initKeyBindingAuthRequestBinder(WebDataBinder binder) { + binder.setValidator(vciExchangeRequestValidator); + } + + /** + * Controller Method to validate the token returned after successful authentication and + * returns a Verifiable Credential. + * + * @param vciExchangeRequestDTO the VCI Exchange request DTO + * @param errors the errors + * @return kycAuthResponseDTO the kyc response DTO + * @throws IdAuthenticationBusinessException the id authentication business exception + * @throws IdAuthenticationAppException the id authentication app exception + * @throws IdAuthenticationDaoException the id authentication dao exception + */ + @PostMapping(path = "/vci-exchange/delegated/{IdP-LK}/{Auth-Partner-ID}/{OIDC-Client-Id}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Verifiable Credential Issuance Request", description = "to issue verifiable credential after token validation", tags = { "vci-controller" }) + @SecurityRequirement(name = "Authorization") + @Parameter(in = ParameterIn.HEADER, name = "signature") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Request authenticated successfully", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = IdAuthenticationAppException.class)))), + @ApiResponse(responseCode = "201", description = "Created" ,content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "401", description = "Unauthorized" ,content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "403", description = "Forbidden" ,content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "404", description = "Not Found" ,content = @Content(schema = @Schema(hidden = true)))}) + public VciExchangeResponseDTO vciExchange(@Validated @RequestBody VciExchangeRequestDTO vciExchangeRequestDTO, + @ApiIgnore Errors errors, @PathVariable("IdP-LK") String idpLK, + @PathVariable("Auth-Partner-ID") String partnerId, + @PathVariable("OIDC-Client-Id") String oidcClientId, + HttpServletRequest request) + throws IdAuthenticationBusinessException, IdAuthenticationAppException, IdAuthenticationDaoException { + if(request instanceof ObjectWithMetadata) { + ObjectWithMetadata requestWrapperWithMetadata = (ObjectWithMetadata) request; + + Optional partner = partnerService.getPartner(partnerId, vciExchangeRequestDTO.getMetadata()); + AuthTransactionBuilder authTxnBuilder = authTransactionHelper + .createAndSetAuthTxnBuilderMetadataToRequest(vciExchangeRequestDTO, false, partner); + try { + + String idType = Objects.nonNull(vciExchangeRequestDTO.getIndividualIdType()) ? vciExchangeRequestDTO.getIndividualIdType() + : idTypeUtil.getIdType(vciExchangeRequestDTO.getIndividualId()).getType(); + vciExchangeRequestDTO.setIndividualIdType(idType); + vciExchangeRequestValidator.validateIdvId(vciExchangeRequestDTO.getIndividualId(), idType, errors); + DataValidationUtil.validate(errors); + + Map metadata = vciExchangeRequestDTO.getMetadata(); + VciExchangeResponseDTO vciExchangeResponseDTO = vciFacade.processVciExchange(vciExchangeRequestDTO, partnerId, + oidcClientId, metadata, requestWrapperWithMetadata); + + return vciExchangeResponseDTO; + } catch (IDDataValidationException e) { + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "processIdKeyBinding", + e.getErrorTexts().isEmpty() ? "" : e.getErrorText()); + + IdaRequestResponsConsumerUtil.setIdVersionToObjectWithMetadata(requestWrapperWithMetadata, e); + if(vciExchangeRequestDTO.getTransactionID() == null) + vciExchangeRequestDTO.setTransactionID(IdAuthCommonConstants.NO_TRANSACTION_ID); + e.putMetadata(IdAuthCommonConstants.TRANSACTION_ID, vciExchangeRequestDTO.getTransactionID()); + throw authTransactionHelper.createDataValidationException(authTxnBuilder, e, requestWrapperWithMetadata); + } catch (IdAuthenticationBusinessException e) { + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "processIdKeyBinding", + e.getErrorTexts().isEmpty() ? "" : e.getErrorText()); + + authTransactionHelper.setAuthTransactionEntityMetadata(e, authTxnBuilder, requestWrapperWithMetadata); + authTransactionHelper.setAuthTransactionEntityMetadata(requestWrapperWithMetadata, authTxnBuilder); + IdaRequestResponsConsumerUtil.setIdVersionToObjectWithMetadata(requestWrapperWithMetadata, e); + e.putMetadata(IdAuthCommonConstants.TRANSACTION_ID, vciExchangeRequestDTO.getTransactionID()); + throw new IdAuthenticationAppException(e.getErrorCode(), e.getErrorText(), e); + } + } else { + mosipLogger.error("Technical error. HttpServletRequest is not instanceof ObjectWithMetada."); + throw new IdAuthenticationBusinessException(IdAuthenticationErrorConstants.UNABLE_TO_PROCESS); + } + } +} \ No newline at end of file diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/facade/KycFacadeImpl.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/facade/KycFacadeImpl.java index 5b161f4abf5..2b94fa585ef 100644 --- a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/facade/KycFacadeImpl.java +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/facade/KycFacadeImpl.java @@ -30,6 +30,7 @@ import io.mosip.authentication.common.service.entity.OIDCClientData; import io.mosip.authentication.common.service.helper.AuditHelper; import io.mosip.authentication.common.service.helper.IdInfoHelper; +import io.mosip.authentication.common.service.helper.TokenValidationHelper; import io.mosip.authentication.common.service.integration.TokenIdManager; import io.mosip.authentication.common.service.repository.IdaUinHashSaltRepo; import io.mosip.authentication.common.service.repository.KycTokenDataRepository; @@ -134,10 +135,7 @@ public class KycFacadeImpl implements KycFacade { private KycTokenDataRepository kycTokenDataRepo; @Autowired - private IdInfoHelper idInfoHelper; - - @Autowired - private OIDCClientDataRepository oidcClientDataRepo; + private TokenValidationHelper tokenValidationHelper; /* * (non-Javadoc) @@ -382,32 +380,22 @@ public KycExchangeResponseDTO processKycExchange(KycExchangeRequestDTO kycExchan String oidcClientId, Map metadata, ObjectWithMetadata requestWithMetadata) throws IdAuthenticationBusinessException { String idHash = null; try { - idHash = securityManager.hash(kycExchangeRequestDTO.getIndividualId()); - mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "processKycExchance", + mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "processKycExchange", "Processing Kyc Exchange request."); - String kycToken = kycExchangeRequestDTO.getKycToken(); - mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "isKycTokenExist", - "Check Token Exists or not, associated with oidc client and active status."); - - Optional kycTokenDataOpt = kycTokenDataRepo.findByKycToken(kycToken); - if (!kycTokenDataOpt.isPresent()) { - mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "processKycExchance", - "KYC Token not found: " + kycToken); - throw new IdAuthenticationBusinessException( - IdAuthenticationErrorConstants.KYC_TOKEN_NOT_FOUND.getErrorCode(), - IdAuthenticationErrorConstants.KYC_TOKEN_NOT_FOUND.getErrorMessage()); - } - KycTokenData kycTokenData = kycTokenDataOpt.get(); - validateKycToken(kycTokenData, oidcClientId, kycExchangeRequestDTO.getTransactionID()); - + String vciAuthToken = kycExchangeRequestDTO.getKycToken(); String idVid = kycExchangeRequestDTO.getIndividualId(); + String idvidHash = securityManager.hash(idVid); + + KycTokenData kycTokenData = tokenValidationHelper.findAndValidateIssuedToken(vciAuthToken, oidcClientId, + kycExchangeRequestDTO.getTransactionID(), idvidHash); + String idvIdType = kycExchangeRequestDTO.getIndividualIdType(); Optional policyForPartner = partnerService.getPolicyForPartner(partnerId, oidcClientId, metadata); Optional policyDtoOpt = policyForPartner.map(PartnerPolicyResponseDTO::getPolicy); if (!policyDtoOpt.isPresent()) { - mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "processKycExchance", + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "processKycExchange", "Partner Policy not found: " + partnerId + ", client id: " + oidcClientId); throw new IdAuthenticationBusinessException( IdAuthenticationErrorConstants.PARTNER_POLICY_NOT_FOUND.getErrorCode(), @@ -415,15 +403,15 @@ public KycExchangeResponseDTO processKycExchange(KycExchangeRequestDTO kycExchan } List consentAttributes = kycExchangeRequestDTO.getConsentObtained(); - List allowedConsentAttributes = filterAllowedUserClaims(oidcClientId, consentAttributes); + List allowedConsentAttributes = tokenValidationHelper.filterAllowedUserClaims(oidcClientId, consentAttributes); PolicyDTO policyDto = policyDtoOpt.get(); List policyAllowedKycAttribs = Optional.ofNullable(policyDto.getAllowedKycAttributes()).stream() .flatMap(Collection::stream).map(KYCAttributes::getAttributeName).collect(Collectors.toList()); Set filterAttributes = new HashSet<>(); - mapConsentedAttributesToIdSchemaAttributes(allowedConsentAttributes, filterAttributes, policyAllowedKycAttribs); - Set policyAllowedAttributes = filterByPolicyAllowedAttributes(filterAttributes, policyAllowedKycAttribs); + tokenValidationHelper.mapConsentedAttributesToIdSchemaAttributes(allowedConsentAttributes, filterAttributes, policyAllowedKycAttribs); + Set policyAllowedAttributes = tokenValidationHelper.filterByPolicyAllowedAttributes(filterAttributes, policyAllowedKycAttribs); boolean isBioRequired = false; if (filterAttributes.contains(CbeffDocType.FACE.getType().value().toLowerCase()) || @@ -437,14 +425,15 @@ public KycExchangeResponseDTO processKycExchange(KycExchangeRequestDTO kycExchan Map> idInfo = IdInfoFetcher.getIdInfo(idResDTO); String token = idService.getToken(idResDTO); - String psuToken = kycTokenDataOpt.get().getPsuToken(); + String psuToken = kycTokenData.getPsuToken(); List locales = kycExchangeRequestDTO.getLocales(); if (locales.size() == 0) { locales.add(EnvUtil.getKycExchangeDefaultLanguage()); } - String respJson = kycService.buildKycExchangeResponse(psuToken, idInfo, allowedConsentAttributes, locales, idVid); + String respJson = kycService.buildKycExchangeResponse(psuToken, idInfo, allowedConsentAttributes, locales, idVid, + kycExchangeRequestDTO); // update kyc token status //KycTokenData kycTokenData = kycTokenDataOpt.get(); kycTokenData.setKycTokenStatus(KycTokenStatusType.PROCESSED.getStatus()); @@ -453,7 +442,7 @@ public KycExchangeResponseDTO processKycExchange(KycExchangeRequestDTO kycExchan kycExchangeResponseDTO.setId(kycExchangeRequestDTO.getId()); kycExchangeResponseDTO.setTransactionID(kycExchangeRequestDTO.getTransactionID()); kycExchangeResponseDTO.setVersion(kycExchangeRequestDTO.getVersion()); - kycExchangeResponseDTO.setResponseTime(getKycExchangeResponseTime(kycExchangeRequestDTO)); + kycExchangeResponseDTO.setResponseTime(tokenValidationHelper.getKycExchangeResponseTime(kycExchangeRequestDTO)); EncryptedKycRespDTO encryptedKycRespDTO = new EncryptedKycRespDTO(); encryptedKycRespDTO.setEncryptedKyc(respJson); @@ -470,88 +459,6 @@ public KycExchangeResponseDTO processKycExchange(KycExchangeRequestDTO kycExchan } } - private void validateKycToken(KycTokenData kycTokenData, String oidcClientId, String reqTransactionId) - throws IdAuthenticationBusinessException { - String kycToken = kycTokenData.getKycToken(); - if (kycTokenData.getKycTokenStatus().equals(KycTokenStatusType.PROCESSED.getStatus())) { - mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "processKycExchance", - "KYC Token already processed: " + kycToken); - throw new IdAuthenticationBusinessException( - IdAuthenticationErrorConstants.KYC_TOKEN_ALREADY_PROCESSED.getErrorCode(), - IdAuthenticationErrorConstants.KYC_TOKEN_ALREADY_PROCESSED.getErrorMessage()); - } - if (!kycTokenData.getOidcClientId().equals(oidcClientId)) { - mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "processKycExchance", - "KYC Token does not belongs to the provided OIDC Client Id: " + kycToken); - throw new IdAuthenticationBusinessException( - IdAuthenticationErrorConstants.KYC_TOKEN_INVALID_OIDC_CLIENT_ID.getErrorCode(), - IdAuthenticationErrorConstants.KYC_TOKEN_INVALID_OIDC_CLIENT_ID.getErrorMessage()); - } - if (!kycTokenData.getRequestTransactionId().equals(reqTransactionId)) { - mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "processKycExchance", - "KYC Auth & KYC Exchange Transaction Ids are not same: " + kycToken); - throw new IdAuthenticationBusinessException( - IdAuthenticationErrorConstants.KYC_TOKEN_INVALID_TRANSACTION_ID.getErrorCode(), - IdAuthenticationErrorConstants.KYC_TOKEN_INVALID_TRANSACTION_ID.getErrorMessage()); - } - - mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "processKycExchance", - "KYC Token found, Check Token expire."); - LocalDateTime tokenIssuedDateTime = kycTokenData.getTokenIssuedDateTime(); - boolean isExpired = kycService.isKycTokenExpire(tokenIssuedDateTime, kycToken); - - if (isExpired) { - mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "checkKycTokenExpire", - "KYC Token expired."); - kycTokenData.setKycTokenStatus(KycTokenStatusType.EXPIRED.getStatus()); - kycTokenDataRepo.saveAndFlush(kycTokenData); - throw new IdAuthenticationBusinessException( - IdAuthenticationErrorConstants.KYC_TOKEN_EXPIRED.getErrorCode(), - IdAuthenticationErrorConstants.KYC_TOKEN_EXPIRED.getErrorMessage()); - } - } - - private void mapConsentedAttributesToIdSchemaAttributes(List consentAttributes, Set filterAttributes, - List policyAllowedKycAttribs) throws IdAuthenticationBusinessException { - - if(consentAttributes != null && !consentAttributes.isEmpty()) { - for (String attrib : consentAttributes) { - Collection idSchemaAttribute = idInfoHelper.getIdentityAttributesForIdName(attrib); - filterAttributes.addAll(idSchemaAttribute); - } - // removing individual id from consent if the claim is not allowed in policy. - if (!policyAllowedKycAttribs.contains(consentedIndividualIdAttributeName)) { - consentAttributes.remove(consentedIndividualIdAttributeName); - } - } - } - - private Set filterByPolicyAllowedAttributes(Set filterAttributes, List policyAllowedKycAttribs) { - return policyAllowedKycAttribs.stream() - .filter(attribute -> filterAttributes.contains(attribute)) - .collect(Collectors.toSet()); - } - - private String getKycExchangeResponseTime(KycExchangeRequestDTO kycExchangeRequestDTO) { - String dateTimePattern = EnvUtil.getDateTimePattern(); - return IdaRequestResponsConsumerUtil.getResponseTime(kycExchangeRequestDTO.getRequestTime(), dateTimePattern); - } - - private List filterAllowedUserClaims(String oidcClientId, List consentAttributes) { - mosipLogger.info(IdAuthCommonConstants.IDA, this.getClass().getSimpleName(), "processKycExchange", - "Checking for OIDC client allowed userclaims"); - Optional oidcClientData = oidcClientDataRepo.findByClientId(oidcClientId); - - List oidcClientAllowedUserClaims = List.of(oidcClientData.get().getUserClaims()) - .stream() - .map(String::toLowerCase) - .collect(Collectors.toList()); - - return consentAttributes.stream() - .filter(claim -> oidcClientAllowedUserClaims.contains(claim.toLowerCase())) - .collect(Collectors.toList()); - - } // Need to move below duplicate code to common to be used by OTPService and KycExchange. private void saveToTxnTable(KycExchangeRequestDTO kycExchangeRequestDTO, boolean isInternal, boolean status, String partnerId, String token, diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/facade/VciFacadeImpl.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/facade/VciFacadeImpl.java new file mode 100644 index 00000000000..19b7b49ef92 --- /dev/null +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/facade/VciFacadeImpl.java @@ -0,0 +1,227 @@ +/** + * + */ +package io.mosip.authentication.service.kyc.facade; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import io.mosip.authentication.common.manager.IdAuthFraudAnalysisEventManager; +import io.mosip.authentication.common.service.builder.AuthTransactionBuilder; +import io.mosip.authentication.common.service.entity.AutnTxn; +import io.mosip.authentication.common.service.entity.KycTokenData; +import io.mosip.authentication.common.service.helper.AuditHelper; +import io.mosip.authentication.common.service.helper.TokenValidationHelper; +import io.mosip.authentication.common.service.integration.TokenIdManager; +import io.mosip.authentication.common.service.repository.IdaUinHashSaltRepo; +import io.mosip.authentication.common.service.repository.KycTokenDataRepository; +import io.mosip.authentication.common.service.transaction.manager.IdAuthSecurityManager; +import io.mosip.authentication.common.service.util.EnvUtil; +import io.mosip.authentication.core.constant.AuditEvents; +import io.mosip.authentication.core.constant.AuditModules; +import io.mosip.authentication.core.constant.IdAuthCommonConstants; +import io.mosip.authentication.core.constant.IdAuthenticationErrorConstants; +import io.mosip.authentication.core.constant.KycTokenStatusType; +import io.mosip.authentication.core.constant.RequestType; +import io.mosip.authentication.core.dto.ObjectWithMetadata; +import io.mosip.authentication.core.exception.IdAuthenticationBusinessException; +import io.mosip.authentication.core.indauth.dto.IdType; +import io.mosip.authentication.core.indauth.dto.IdentityInfoDTO; +import io.mosip.authentication.core.indauth.dto.VCResponseDTO; +import io.mosip.authentication.core.indauth.dto.VciExchangeRequestDTO; +import io.mosip.authentication.core.indauth.dto.VciExchangeResponseDTO; +import io.mosip.authentication.core.logger.IdaLogger; +import io.mosip.authentication.core.partner.dto.KYCAttributes; +import io.mosip.authentication.core.partner.dto.PartnerDTO; +import io.mosip.authentication.core.partner.dto.PartnerPolicyResponseDTO; +import io.mosip.authentication.core.partner.dto.PolicyDTO; +import io.mosip.authentication.core.spi.bioauth.CbeffDocType; +import io.mosip.authentication.core.spi.id.service.IdService; +import io.mosip.authentication.core.spi.indauth.facade.VciFacade; +import io.mosip.authentication.core.spi.indauth.match.IdInfoFetcher; +import io.mosip.authentication.core.spi.partner.service.PartnerService; +import io.mosip.authentication.service.kyc.impl.VciServiceImpl; +import io.mosip.kernel.core.logger.spi.Logger; + +/** + * + * + * Facade to Verifiable Credential details + * + * @author Dinesh Karuppiah.T + */ +@Component +public class VciFacadeImpl implements VciFacade { + + /** The mosip logger. */ + private static Logger mosipLogger = IdaLogger.getLogger(VciFacadeImpl.class); + + /** The env. */ + @Autowired + private EnvUtil env; + + /** The Id Info Service */ + @Autowired + private IdService idService; + + /** The AuditHelper */ + @Autowired + private AuditHelper auditHelper; + + @Autowired + private IdaUinHashSaltRepo uinHashSaltRepo; + + /** The TokenId manager */ + @Autowired + private TokenIdManager tokenIdManager; + + @Autowired + private IdAuthSecurityManager securityManager; + + @Autowired + private PartnerService partnerService; + + @Autowired + private IdAuthFraudAnalysisEventManager fraudEventManager; + + @Autowired + private VciServiceImpl vciServiceImpl; + + @Autowired + private TokenValidationHelper tokenValidationHelper; + + @Autowired + private KycTokenDataRepository kycTokenDataRepo; + + @Override + public VciExchangeResponseDTO processVciExchange(VciExchangeRequestDTO vciExchangeRequestDTO, String partnerId, + String oidcClientId, Map metadata, ObjectWithMetadata requestWithMetadata) throws IdAuthenticationBusinessException { + String idvidHash = null; + try { + mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "processVciExchange", + "Processing VCI Exchange request."); + + String vciAuthToken = vciExchangeRequestDTO.getVcAuthToken(); + String idVid = vciExchangeRequestDTO.getIndividualId(); + idvidHash = securityManager.hash(idVid); + + KycTokenData kycTokenData = tokenValidationHelper.findAndValidateIssuedToken(vciAuthToken, oidcClientId, + vciExchangeRequestDTO.getTransactionID(), idvidHash); + + String idvIdType = vciExchangeRequestDTO.getIndividualIdType(); + Optional policyForPartner = partnerService.getPolicyForPartner(partnerId, oidcClientId, metadata); + Optional policyDtoOpt = policyForPartner.map(PartnerPolicyResponseDTO::getPolicy); + + if (!policyDtoOpt.isPresent()) { + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "processKycExchange", + "Partner Policy not found: " + partnerId + ", client id: " + oidcClientId); + throw new IdAuthenticationBusinessException( + IdAuthenticationErrorConstants.PARTNER_POLICY_NOT_FOUND.getErrorCode(), + IdAuthenticationErrorConstants.PARTNER_POLICY_NOT_FOUND.getErrorMessage()); + } + + // Will implement later the consent claims based on credential definition input + List consentAttributes = Collections.emptyList(); + List allowedConsentAttributes = tokenValidationHelper.filterAllowedUserClaims(oidcClientId, consentAttributes); + + PolicyDTO policyDto = policyDtoOpt.get(); + List policyAllowedKycAttribs = Optional.ofNullable(policyDto.getAllowedKycAttributes()).stream() + .flatMap(Collection::stream).map(KYCAttributes::getAttributeName).collect(Collectors.toList()); + + Set filterAttributes = new HashSet<>(); + tokenValidationHelper.mapConsentedAttributesToIdSchemaAttributes(allowedConsentAttributes, filterAttributes, policyAllowedKycAttribs); + Set policyAllowedAttributes = tokenValidationHelper.filterByPolicyAllowedAttributes(filterAttributes, policyAllowedKycAttribs); + + boolean isBioRequired = false; + if (filterAttributes.contains(CbeffDocType.FACE.getType().value().toLowerCase()) || + filterAttributes.contains(IdAuthCommonConstants.PHOTO.toLowerCase())) { + policyAllowedAttributes.add(CbeffDocType.FACE.getType().value().toLowerCase()); + isBioRequired = true; + } + + Map idResDTO = idService.processIdType(idvIdType, idVid, isBioRequired, + IdAuthCommonConstants.VCI_EXCHANGE_CONSUME_VID_DEFAULT, policyAllowedAttributes); + + String token = idService.getToken(idResDTO); + + vciServiceImpl.addCredSubjectId(vciExchangeRequestDTO.getCredSubjectId(), idvidHash, token, oidcClientId); + mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "processVciExchange", + "Added Credential Subject Id complete."); + + Map> idInfo = IdInfoFetcher.getIdInfo(idResDTO); + + String psuToken = kycTokenData.getPsuToken(); + List locales = vciExchangeRequestDTO.getLocales(); + if (Objects.isNull(locales) || locales.size() == 0) { + locales = new ArrayList<>(); // throws NullPointer if locales is null + locales.add(EnvUtil.getKycExchangeDefaultLanguage()); + } + + VCResponseDTO vcResponseDTO = vciServiceImpl.buildVerifiableCredentials(vciExchangeRequestDTO.getCredSubjectId(), vciExchangeRequestDTO.getVcFormat(), + idInfo, locales, policyAllowedAttributes, vciExchangeRequestDTO, psuToken); + + // update kyc token status + kycTokenData.setKycTokenStatus(KycTokenStatusType.PROCESSED.getStatus()); + kycTokenDataRepo.saveAndFlush(kycTokenData); + VciExchangeResponseDTO vciExchangeResponseDTO = new VciExchangeResponseDTO(); + vciExchangeResponseDTO.setId(vciExchangeRequestDTO.getId()); + vciExchangeResponseDTO.setTransactionID(vciExchangeRequestDTO.getTransactionID()); + vciExchangeResponseDTO.setVersion(vciExchangeRequestDTO.getVersion()); + vciExchangeResponseDTO.setResponseTime(tokenValidationHelper.getKycExchangeResponseTime(vciExchangeRequestDTO)); + vciExchangeResponseDTO.setResponse(vcResponseDTO); + saveToTxnTable(vciExchangeRequestDTO, false, true, partnerId, token, vciExchangeResponseDTO, requestWithMetadata); + auditHelper.audit(AuditModules.VCI_EXCHANGE, AuditEvents.VCI_EXCHANGE_REQUEST_RESPONSE, + idvidHash, IdType.getIDTypeOrDefault(vciExchangeRequestDTO.getIndividualIdType()), + IdAuthCommonConstants.VCI_EXCHANGE_SUCCESS); + return vciExchangeResponseDTO; + } catch(IdAuthenticationBusinessException e) { + auditHelper.audit(AuditModules.VCI_EXCHANGE, AuditEvents.VCI_EXCHANGE_REQUEST_RESPONSE, + idvidHash, IdType.getIDTypeOrDefault(vciExchangeRequestDTO.getIndividualIdType()), e); + throw e; + } + } + + // Need to move below duplicate code to common to be used by OTPService and KycExchange. + private void saveToTxnTable(VciExchangeRequestDTO vciExchangeRequestDTO, boolean isInternal, boolean status, String partnerId, String token, + VciExchangeResponseDTO vciExchangeResponseDTO, ObjectWithMetadata requestWithMetadata) + throws IdAuthenticationBusinessException { + if (token != null) { + boolean authTokenRequired = !isInternal + && EnvUtil.getAuthTokenRequired(); + String authTokenId = authTokenRequired ? tokenIdManager.generateTokenId(token, partnerId) : null; + saveTxn(vciExchangeRequestDTO, token, authTokenId, status, partnerId, isInternal, vciExchangeResponseDTO, requestWithMetadata); + } + } + + private void saveTxn(VciExchangeRequestDTO vciExchangeRequestDTO, String token, String authTokenId, + boolean status, String partnerId, boolean isInternal, VciExchangeResponseDTO vciExchangeResponseDTO, ObjectWithMetadata requestWithMetadata) + throws IdAuthenticationBusinessException { + Optional partner = isInternal ? Optional.empty() : partnerService.getPartner(partnerId, vciExchangeRequestDTO.getMetadata()); + AutnTxn authTxn = AuthTransactionBuilder.newInstance() + .withRequest(vciExchangeRequestDTO) + .addRequestType(RequestType.VCI_EXCHANGE_REQUEST) + .withAuthToken(authTokenId) + .withStatus(status) + .withToken(token) + .withPartner(partner) + .withInternal(isInternal) + .build(env,uinHashSaltRepo,securityManager); + fraudEventManager.analyseEvent(authTxn); + if(requestWithMetadata != null) { + requestWithMetadata.setMetadata(Map.of(AutnTxn.class.getSimpleName(), authTxn)); + } else { + idService.saveAutnTxn(authTxn); + } + } +} diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/filter/VciExchangeFilter.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/filter/VciExchangeFilter.java new file mode 100644 index 00000000000..54b6ff05667 --- /dev/null +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/filter/VciExchangeFilter.java @@ -0,0 +1,115 @@ +package io.mosip.authentication.service.kyc.filter; + +import java.util.List; +import java.util.Map; + +import org.springframework.stereotype.Component; + +import io.mosip.authentication.common.service.filter.IdAuthFilter; +import io.mosip.authentication.common.service.filter.ResettableStreamHttpServletRequest; +import io.mosip.authentication.core.constant.IdAuthCommonConstants; +import io.mosip.authentication.core.constant.IdAuthenticationErrorConstants; +import io.mosip.authentication.core.exception.IdAuthenticationAppException; +import io.mosip.authentication.core.logger.IdaLogger; +import io.mosip.authentication.core.partner.dto.AuthPolicy; +import io.mosip.authentication.core.partner.dto.MispPolicyDTO; +import io.mosip.kernel.core.logger.spi.Logger; + +/** + * The Class VciExchangeFilter - used to validate the request and returns + * Verifiable Credentials as response. + * + * @author Mahammed Taheer + */ +@Component +public class VciExchangeFilter extends IdAuthFilter { + + private static Logger mosipLogger = IdaLogger.getLogger(VciExchangeFilter.class); + + /** The Constant KYC. */ + private static final String VCI_EXCHANGE = "vciexchange"; + + @Override + protected boolean isPartnerCertificateNeeded() { + return true; + } + + /* + * (non-Javadoc) + * + * @see io.mosip.authentication.service.filter.IdAuthFilter# + * checkAllowedAuthTypeBasedOnPolicy(java.util.Map, java.util.List) + */ + @Override + protected void checkAllowedAuthTypeBasedOnPolicy(Map requestBody, List authPolicies) + throws IdAuthenticationAppException { + if (!isAllowedAuthType(VCI_EXCHANGE, authPolicies)) { + throw new IdAuthenticationAppException(IdAuthenticationErrorConstants.UNAUTHORISED_VCI_EXCHANGE_PARTNER.getErrorCode(), + IdAuthenticationErrorConstants.UNAUTHORISED_VCI_EXCHANGE_PARTNER.getErrorMessage()); + + } + } + + /* (non-Javadoc) + * @see io.mosip.authentication.common.service.filter.IdAuthFilter#checkMandatoryAuthTypeBasedOnPolicy(java.util.Map, java.util.List) + */ + @Override + protected void checkMandatoryAuthTypeBasedOnPolicy(Map requestBody, + List mandatoryAuthPolicies) throws IdAuthenticationAppException { + // Nothing to do + } + + @Override + protected boolean isSigningRequired() { + return true; + } + + @Override + protected boolean isSignatureVerificationRequired() { + return true; + } + + @Override + protected boolean isTrustValidationRequired() { + return true; + } + + @Override + protected String fetchId(ResettableStreamHttpServletRequest requestWrapper, String attribute) { + return attribute + VCI_EXCHANGE; + } + + protected boolean needStoreAuthTransaction() { + return true; + } + + protected boolean needStoreAnonymousProfile() { + return true; + } + + @Override + protected boolean isMispPolicyValidationRequired() { + return true; + } + + @Override + protected boolean isCertificateValidationRequired() { + return true; + } + + @Override + protected boolean isAMRValidationRequired() { + return false; + } + + @Override + protected void checkMispPolicyAllowed(MispPolicyDTO mispPolicy) throws IdAuthenticationAppException { + // check whether policy is allowed for vci exchange or not. + if (!mispPolicy.isAllowVciRequestDelegation()) { + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getCanonicalName(), "checkMispPolicyAllowed", + "MISP Partner not allowed for the Auth Type - vci-exchange."); + throw new IdAuthenticationAppException(IdAuthenticationErrorConstants.VCI_EXCHANGE_NOT_ALLOWED.getErrorCode(), + String.format(IdAuthenticationErrorConstants.VCI_EXCHANGE_NOT_ALLOWED.getErrorMessage(), "VCI-EXCHANGE")); + } + } +} diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/impl/KycServiceImpl.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/impl/KycServiceImpl.java index 57dd5b97712..d456c2b2221 100644 --- a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/impl/KycServiceImpl.java +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/impl/KycServiceImpl.java @@ -41,6 +41,7 @@ import io.mosip.authentication.core.exception.IdAuthenticationBusinessException; import io.mosip.authentication.core.indauth.dto.EKycResponseDTO; import io.mosip.authentication.core.indauth.dto.IdentityInfoDTO; +import io.mosip.authentication.core.indauth.dto.KycExchangeRequestDTO; import io.mosip.authentication.core.logger.IdaLogger; import io.mosip.authentication.core.spi.bioauth.CbeffDocType; import io.mosip.authentication.core.spi.indauth.match.MappingConfig; @@ -95,6 +96,9 @@ public class KycServiceImpl implements KycService { @Value("${ida.kyc.send-face-as-cbeff-xml:false}") private boolean sendFaceAsCbeffXml; + @Value("${ida.idp.jwe.response.type.constant:JWE}") + private String jweResponseType; + /** The env. */ @Autowired EnvUtil env; @@ -448,7 +452,7 @@ public boolean isKycTokenExpire(LocalDateTime tokenIssuedDateTime, String kycTok @Override public String buildKycExchangeResponse(String subject, Map> idInfo, - List consentedAttributes, List consentedLocales, String idVid) throws IdAuthenticationBusinessException { + List consentedAttributes, List consentedLocales, String idVid, KycExchangeRequestDTO kycExchangeRequestDTO) throws IdAuthenticationBusinessException { mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "buildKycExchangeResponse", "Building claims response for PSU token: " + subject); @@ -473,7 +477,13 @@ public String buildKycExchangeResponse(String subject, Map vcContextUrlMap; + + @Value("${mosip.ida.vercred.context.uri:}") + private String vcContextUri; + + @Value("${mosip.ida.vercred.id.url:}") + private String verCredIdUrl; + + @Value("${ida.idp.consented.picture.attribute.prefix:data:image/jpeg;base64,}") + private String consentedPictureAttributePrefix; + + @Value("${mosip.ida.vercred.issuer.url:}") + private String verCredIssuer; + + @Value("${mosip.ida.vercred.proof.purpose:}") + private String proofPurpose; + + @Value("${mosip.ida.vercred.proof.type:}") + private String proofType; + + @Value("${mosip.ida.vercred.proof.verificationmethod:}") + private String verificationMethod; + + private ConfigurableDocumentLoader confDocumentLoader; + + private JSONObject vcContextJsonld; + + @Autowired + private IdAuthSecurityManager securityManager; + + @Autowired + private CredSubjectIdStoreRepository csidStoreRepo; + + @Autowired + private VCSchemaProviderUtil vcSchemaProviderUtil; + + /** The demo helper. */ + @Autowired + private IdInfoHelper idInfoHelper; + + @Autowired + private CbeffUtil cbeffUtil; + + @PostConstruct + private void init() throws IdAuthenticationBusinessException { + if(Objects.isNull(vcContextUrlMap)){ + mosipLogger.warn(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "VciServiceImpl::init", + "Warning - Verifiable Credential Context URL Map not configured, VC generation may fail."); + confDocumentLoader = new ConfigurableDocumentLoader(); + confDocumentLoader.setEnableHttps(true); + confDocumentLoader.setEnableHttp(true); + confDocumentLoader.setEnableFile(false); + } else { + Map jsonDocumentCacheMap = new HashMap (); + vcContextUrlMap.keySet().stream().forEach(contextUrl -> { + String localConfigUri = vcContextUrlMap.get(contextUrl); + JsonDocument jsonDocument = vcSchemaProviderUtil.getVCContextSchema(configServerFileStorageUrl, localConfigUri); + try { + jsonDocumentCacheMap.put(new URI(contextUrl), jsonDocument); + } catch (URISyntaxException e) { + mosipLogger.warn(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "VciServiceImpl::init", + "Warning - Verifiable Credential URI not able to add to cacheMap."); + } + }); + confDocumentLoader = new ConfigurableDocumentLoader(jsonDocumentCacheMap); + confDocumentLoader.setEnableHttps(false); + confDocumentLoader.setEnableHttp(false); + confDocumentLoader.setEnableFile(false); + mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "VciServiceImpl::init", + "Added cache for the list of configured URL Map: " + jsonDocumentCacheMap.keySet().toString()); + } + vcContextJsonld = vcSchemaProviderUtil.getVCContextData(configServerFileStorageUrl, vcContextUri, OBJECT_MAPPER); + } + + @Override + public void addCredSubjectId(String credSubjectId, String idVidHash, String tokenId, String oidcClientId) + throws IdAuthenticationBusinessException { + + mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "addCredSubjectId", + "Add Cred Subject Id for Id/Vid:" + idVidHash); + String[] didArray = StringUtils.split(credSubjectId, COLON); + String identityJwk = new String(CryptoUtil.decodeBase64(didArray[2])); + JSONObject jsonObject = null; + try { + jsonObject = OBJECT_MAPPER.readValue(identityJwk, JSONObject.class); + } catch (IOException ioe) { + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "addCredSubjectId", + "Error parsing Identity JWK", ioe); + throw new IdAuthenticationBusinessException(IdAuthenticationErrorConstants.UNABLE_TO_PROCESS, ioe); + } + + String identityKeyHash = getPublicKeyHash(jsonObject); + List credSubjectIdList = csidStoreRepo.findAllByCsidKeyHash(identityKeyHash); + // Case 0: key not exists. List size is zero + if (credSubjectIdList.size() == 0) { + mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "addCredSubjectId", + "Input Key not present, adding the did jwk in the store."); + addCredSubjectId(credSubjectId, idVidHash, tokenId, oidcClientId, identityKeyHash); + return; + } + + // Case 1: key exists but mapped to same id/vid and same token id + boolean sameIdVid = credSubjectIdList.stream().anyMatch(credSubId -> credSubId.getIdVidHash().equals(idVidHash) && + credSubId.getTokenId().equals(tokenId)); + if (sameIdVid) { + mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "addCredSubjectId", + "Input Key already available and mapped to same id/vid and token id."); + return; + } + // Case 2: key exists but mapped to different id/vid and same token id. + boolean diffIdVidSameToken = credSubjectIdList.stream().anyMatch(credSubId -> !credSubId.getIdVidHash().equals(idVidHash) && + credSubId.getTokenId().equals(tokenId)); + if (diffIdVidSameToken) { + mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "addCredSubjectId", + "Input Key already available and mapped to different id/vid but mapped to same token id. " + + "So, adding new entry in store."); + addCredSubjectId(credSubjectId, idVidHash, tokenId, oidcClientId, identityKeyHash); + return; + } + + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "addCredSubjectId", + "Input Key already available and mapped to different id/vid & token id. " + + "Not allowed to map to input id/vid."); + throw new IdAuthenticationBusinessException( + IdAuthenticationErrorConstants.KEY_ALREADY_MAPPED_ERROR.getErrorCode(), + IdAuthenticationErrorConstants.KEY_ALREADY_MAPPED_ERROR.getErrorMessage()); + + } + + private String getPublicKeyHash(JSONObject jsonObject) throws IdAuthenticationBusinessException{ + + try { + String publicKeyExponent = jsonObject.get(PUBLIC_KEY_EXPONENT_KEY).toString(); + String publicKeyModulus = jsonObject.get(PUBLIC_KEY_MODULUS_KEY).toString(); + String keyType = jsonObject.get(JWK_KEY_TYPE).toString(); + if (keyType.equalsIgnoreCase(IdAuthCommonConstants.ALGORITHM_RSA)) { + KeyFactory keyfactory = KeyFactory.getInstance(IdAuthCommonConstants.ALGORITHM_RSA); + BigInteger modulus = new BigInteger(1, CryptoUtil.decodeBase64Url(publicKeyModulus)); + BigInteger exponent = new BigInteger(1, CryptoUtil.decodeBase64Url(publicKeyExponent)); + PublicKey rsaKey = keyfactory.generatePublic(new RSAPublicKeySpec(modulus, exponent)); + return IdAuthSecurityManager.generateHashAndDigestAsPlainText(rsaKey.getEncoded()); + } + mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "getPublicKeyHash", + "Not Supported Key type."); + throw new IdAuthenticationBusinessException( + IdAuthenticationErrorConstants.KEY_TYPE_NOT_SUPPORT.getErrorCode(), + IdAuthenticationErrorConstants.KEY_TYPE_NOT_SUPPORT.getErrorMessage()); + } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "getPublicKeyHash", + "Error Building Public Key Object.", e); + throw new IdAuthenticationBusinessException( + IdAuthenticationErrorConstants.CREATE_VCI_PUBLIC_KEY_OBJECT_ERROR.getErrorCode(), + IdAuthenticationErrorConstants.CREATE_VCI_PUBLIC_KEY_OBJECT_ERROR.getErrorMessage()); + } + } + + private void addCredSubjectId(String credSubjectId, String idVidHash, String tokenId, + String oidcClientId, String keyHash) { + + String uuid = UUID.randomUUID().toString(); + CredSubjectIdStore credSubjectIdStore = new CredSubjectIdStore(); + credSubjectIdStore.setId(uuid); + credSubjectIdStore.setIdVidHash(idVidHash); + credSubjectIdStore.setTokenId(tokenId); + credSubjectIdStore.setCredSubjectId(credSubjectId); + credSubjectIdStore.setOidcClientId(oidcClientId); + credSubjectIdStore.setCsidKeyHash(keyHash); + credSubjectIdStore.setCsidStatus(VCStatus.ACTIVE.getStatus()); + credSubjectIdStore.setCreatedBy(EnvUtil.getAppId()); + credSubjectIdStore.setCrDTimes(DateUtils.getUTCCurrentDateTime()); + csidStoreRepo.saveAndFlush(credSubjectIdStore); + mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "addCredSubjectId", + "Credential subject Id details Saved."); + } + + @Override + public VCResponseDTO buildVerifiableCredentials(String credSubjectId, String vcFormat, + Map> idInfo, List locales, Set allowedAttributes, + VciExchangeRequestDTO vciExchangeRequestDTO, String psuToken) throws IdAuthenticationBusinessException { + mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "buildVerifiableCredentials", + "Building Verifiable Credentials for format: " + vcFormat); + + switch (VCFormats.valueOf(vcFormat.toUpperCase())) { + case LDP_VC: + JsonLDObject ldObject = generateLdpVc(credSubjectId, idInfo, locales, allowedAttributes, vciExchangeRequestDTO, psuToken); + VCResponseDTO vcResponseDTO = new VCResponseDTO<>(); + vcResponseDTO.setVerifiableCredentials(ldObject); + return vcResponseDTO; + case JWT_VC_JSON: + throw new IdAuthenticationBusinessException(IdAuthenticationErrorConstants.VCI_NOT_SUPPORTED_ERROR); + case JWT_VC_JSON_LD: + throw new IdAuthenticationBusinessException(IdAuthenticationErrorConstants.VCI_NOT_SUPPORTED_ERROR); + default: + throw new IdAuthenticationBusinessException(IdAuthenticationErrorConstants.VCI_NOT_SUPPORTED_ERROR); + } + } + + private JsonLDObject generateLdpVc(String credSubjectId, Map> idInfo, + List locales, Set allowedAttributes, VciExchangeRequestDTO vciExchangeRequestDTO, + String psuToken) throws IdAuthenticationBusinessException { + + Map credSubjectMap = getCredSubjectMap(credSubjectId, idInfo, locales, allowedAttributes); + try { + Map verCredJsonObject = new HashMap<>(); + + // @Context + Object contextObj = vcContextJsonld.get("context"); + verCredJsonObject.put(IdAuthCommonConstants.VC_AT_CONTEXT, contextObj); + + // vc type + verCredJsonObject.put(IdAuthCommonConstants.VC_TYPE, vciExchangeRequestDTO.getCredentialsDefinition().getType()); + + // vc id + String vcId = UUID.randomUUID().toString(); + verCredJsonObject.put(IdAuthCommonConstants.VC_ID, verCredIdUrl + vcId); + + // vc issuer + verCredJsonObject.put(IdAuthCommonConstants.VC_ISSUER, verCredIssuer); + + // vc issuance date + DateTimeFormatter format = DateTimeFormatter.ofPattern(EnvUtil.getDateTimePattern()); + LocalDateTime localdatetime = LocalDateTime.parse(DateUtils.getUTCCurrentDateTimeString(EnvUtil.getDateTimePattern()), format); + verCredJsonObject.put(IdAuthCommonConstants.VC_ISSUANCE_DATE, DateUtils.formatToISOString(localdatetime)); + + // vc credentialSubject + verCredJsonObject.put(IdAuthCommonConstants.CREDENTIALSUBJECT, credSubjectMap); + + // Build the Json LD Object. + JsonLDObject vcJsonLdObject = JsonLDObject.fromJsonObject(verCredJsonObject); + vcJsonLdObject.setDocumentLoader(confDocumentLoader); + + // vc proof + Date created = Date.from(localdatetime.atZone(ZoneId.systemDefault()).toInstant()); + LdProof vcLdProof = LdProof.builder() + .defaultContexts(false) + .defaultTypes(false) + .type(proofType) + .created(created) + .proofPurpose(proofPurpose) + .verificationMethod(new URI(verificationMethod)) + .build(); + + URDNA2015Canonicalizer canonicalizer = new URDNA2015Canonicalizer(); + byte[] vcSignBytes = canonicalizer.canonicalize(vcLdProof, vcJsonLdObject); + String vcEncodedData = CryptoUtil.encodeBase64Url(vcSignBytes); + + String jws = securityManager.jwsSignWithPayload(vcEncodedData); + + LdProof ldProofWithJWS = LdProof.builder() + .base(vcLdProof) + .defaultContexts(false) + .jws(jws) + .build(); + + ldProofWithJWS.addToJsonLDObject(vcJsonLdObject); + mosipLogger.info(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "generateLdpVc", + "Verifiable Credential Generation completed for the provided data."); + return vcJsonLdObject; + } catch (IOException | GeneralSecurityException | JsonLDException | URISyntaxException e) { + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "generateLdpVc", + "Error Building Ldp VC.", e); + throw new IdAuthenticationBusinessException( + IdAuthenticationErrorConstants.LDP_VC_GENERATION_FAILED.getErrorCode(), + IdAuthenticationErrorConstants.LDP_VC_GENERATION_FAILED.getErrorMessage()); + } + } + + private Map getCredSubjectMap(String credSubjectId, Map> idInfo, + List locales, Set allowedAttributes) throws IdAuthenticationBusinessException { + Map credSubjectMap = new HashMap<>(); + + credSubjectMap.put(IdAuthCommonConstants.VC_ID, credSubjectId); + + for (String attrib : allowedAttributes) { + List idSchemaAttributes = idInfoHelper.getIdentityAttributesForIdName(attrib); + if (attrib.equalsIgnoreCase(BiometricType.FACE.value())) { + Map faceEntityInfoMap = idInfoHelper.getIdEntityInfoMap(BioMatchType.FACE, idInfo, null); + if (Objects.nonNull(faceEntityInfoMap)) { + try { + String face = convertJP2ToJpeg(getFaceBDB(faceEntityInfoMap.get(CbeffDocType.FACE.getType().value()))); + if (Objects.nonNull(face)) + credSubjectMap.put(attrib, consentedPictureAttributePrefix + face); + } catch (Exception e) { + // Not throwing any exception because others claims will be returned without photo. + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "", + "Error Adding photo to the claims. " + e.getMessage(), e); + } + + } + } + for (String idSchemaAttribute : idSchemaAttributes) { + List idInfoList = idInfo.get(idSchemaAttribute); + if (Objects.isNull(idInfoList)) + continue; + if (idInfoList.size() == 1) { + IdentityInfoDTO identityInfo = idInfoList.get(0); + if (Objects.isNull(identityInfo.getLanguage())) + credSubjectMap.put(idSchemaAttribute, idInfoList.get(0).getValue()); + else { + Map valueMap = new HashMap<>(); + String lang = identityInfo.getLanguage(); + if (locales.contains(lang)) { + valueMap.put(IdAuthCommonConstants.LANGUAGE_STRING, lang); + valueMap.put(IdAuthCommonConstants.VALUE_STRING, identityInfo.getValue()); + credSubjectMap.put(idSchemaAttribute, valueMap); + } + } + continue; + } + List> valueList = new ArrayList<>(); + for (IdentityInfoDTO identityInfo : idInfoList) { + Map valueMap = new HashMap<>(); + String lang = identityInfo.getLanguage(); + if (locales.contains(lang)) { + valueMap.put(IdAuthCommonConstants.LANGUAGE_STRING, identityInfo.getLanguage()); + valueMap.put(IdAuthCommonConstants.VALUE_STRING, identityInfo.getValue()); + valueList.add(valueMap); + } + } + credSubjectMap.put(idSchemaAttribute, valueList); + } + } + return credSubjectMap; + } + + private String getFaceBDB(String faceCbeff) throws Exception { + List birDataFromXMLType = cbeffUtil.getBIRDataFromXMLType(faceCbeff.getBytes(), CbeffDocType.FACE.getName()); + if(birDataFromXMLType.isEmpty()) { + //This is unlikely as if empty the exception would have been thrown already + throw new IdAuthenticationBusinessException(IdAuthenticationErrorConstants.UNABLE_TO_PROCESS); + } + return CryptoUtil.encodeBase64(birDataFromXMLType.get(0).getBdb()); + } + + private String convertJP2ToJpeg(String jp2Image) { + try { + ConvertRequestDto convertRequestDto = new ConvertRequestDto(); + convertRequestDto.setVersion(IdAuthCommonConstants.FACE_ISO_NUMBER); + convertRequestDto.setInputBytes(CryptoUtil.decodeBase64(jp2Image)); + byte[] image = FaceDecoder.convertFaceISOToImageBytes(convertRequestDto); + return CryptoUtil.encodeBase64(image); + } catch(Exception exp) { + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "convertJP2ToJpeg", + "Error Converting JP2 To JPEG. " + exp.getMessage(), exp); + } + return null; + } +} \ No newline at end of file diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/util/VCSchemaProviderUtil.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/util/VCSchemaProviderUtil.java new file mode 100644 index 00000000000..bc8a3c1fddc --- /dev/null +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/util/VCSchemaProviderUtil.java @@ -0,0 +1,62 @@ +package io.mosip.authentication.service.kyc.util; + +import java.io.IOException; +import java.io.StringReader; + +import org.json.simple.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import com.apicatalog.jsonld.JsonLdError; +import com.apicatalog.jsonld.document.JsonDocument; +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.mosip.authentication.core.constant.IdAuthCommonConstants; +import io.mosip.authentication.core.constant.IdAuthenticationErrorConstants; +import io.mosip.authentication.core.exception.IdAuthUncheckedException; +import io.mosip.authentication.core.exception.IdAuthenticationBusinessException; +import io.mosip.authentication.core.logger.IdaLogger; +import io.mosip.kernel.core.logger.spi.Logger; + +/** + * This class fetches the Verifiable Credentials schema & @Context data. + * + * @author Mahammed Taheer + * + */ +@Component +public class VCSchemaProviderUtil { + + private static Logger logger = IdaLogger.getLogger(VCSchemaProviderUtil.class); + + @Autowired + RestTemplate restTemplate; + + public JsonDocument getVCContextSchema(String configServerFileStorageUrl, String uri) { + try { + String vcContextJson = restTemplate.getForObject(configServerFileStorageUrl + uri, String.class); + JsonDocument jsonDocument = JsonDocument.of(new StringReader(vcContextJson)); + return jsonDocument; + } catch (JsonLdError e) { + logger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "getVCContextSchema", + "Error while getting VC Context Schema Json Document.", e ); + throw new IdAuthUncheckedException(IdAuthenticationErrorConstants.DOWNLOAD_ERROR.getErrorCode(), + IdAuthenticationErrorConstants.DOWNLOAD_ERROR.getErrorMessage()); + } + } + + public JSONObject getVCContextData(String configServerFileStorageURL, String uri, ObjectMapper objectMapper) + throws IdAuthenticationBusinessException { + try { + String vcContextData = restTemplate.getForObject(configServerFileStorageURL + uri, String.class); + JSONObject jsonObject = objectMapper.readValue(vcContextData, JSONObject.class); + return jsonObject; + } catch (IOException e) { + logger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), "getVCContextData", + "error while getting VC Context Json.", e); + throw new IdAuthenticationBusinessException(IdAuthenticationErrorConstants.DOWNLOAD_ERROR.getErrorCode(), + IdAuthenticationErrorConstants.DOWNLOAD_ERROR.getErrorMessage()); + } + } +} diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/validator/IdentityKeyBindingRequestValidator.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/validator/IdentityKeyBindingRequestValidator.java index 56c8d47033d..4025230af0b 100644 --- a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/validator/IdentityKeyBindingRequestValidator.java +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/validator/IdentityKeyBindingRequestValidator.java @@ -29,9 +29,7 @@ * The Class For IdentityKeyBindingRequestValidator extending the * BaseAuthRequestValidator{@link BaseAuthRequestValidator}} * - * @author Prem Kumar - * @author Dinesh Karuppiah.T - * + * @author Mahammed Taheer * */ diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/validator/KycExchangeRequestValidator.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/validator/KycExchangeRequestValidator.java index 0bf007f705a..bcd69d94748 100644 --- a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/validator/KycExchangeRequestValidator.java +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/validator/KycExchangeRequestValidator.java @@ -61,9 +61,10 @@ public void validate(Object target, Errors errors) { validateKycToken(kycExchangeRequestDTO.getKycToken(), errors, IdAuthCommonConstants.KYC_TOKEN); } - if (!errors.hasErrors()) { + // commented below validation because end user can provide nil consent. + /* if (!errors.hasErrors()) { validateConsentObtainedList(kycExchangeRequestDTO.getConsentObtained(), errors, IdAuthCommonConstants.CONSENT_OBTAINED); - } + } */ if (!errors.hasErrors()) { validateTxnId(kycExchangeRequestDTO.getTransactionID(), errors, IdAuthCommonConstants.TRANSACTION_ID); diff --git a/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/validator/VciExchangeRequestValidator.java b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/validator/VciExchangeRequestValidator.java new file mode 100644 index 00000000000..44f81ce6b63 --- /dev/null +++ b/authentication/authentication-service/src/main/java/io/mosip/authentication/service/kyc/validator/VciExchangeRequestValidator.java @@ -0,0 +1,211 @@ +package io.mosip.authentication.service.kyc.validator; + +import static io.mosip.authentication.core.constant.IdAuthCommonConstants.SESSION_ID; +import static io.mosip.authentication.core.constant.IdAuthCommonConstants.PUBLIC_KEY_EXPONENT_KEY; +import static io.mosip.authentication.core.constant.IdAuthCommonConstants.PUBLIC_KEY_MODULUS_KEY; +import static io.mosip.authentication.core.constant.IdAuthCommonConstants.COLON; + +import java.io.IOException; +import java.util.List; +import java.util.stream.Stream; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.module.afterburner.AfterburnerModule; + +import io.mosip.authentication.common.service.validator.AuthRequestValidator; +import io.mosip.authentication.common.service.validator.BaseAuthRequestValidator; +import io.mosip.authentication.core.constant.IdAuthCommonConstants; +import io.mosip.authentication.core.constant.IdAuthenticationErrorConstants; +import io.mosip.authentication.core.constant.VCFormats; +import io.mosip.authentication.core.indauth.dto.VciExchangeRequestDTO; +import io.mosip.authentication.core.logger.IdaLogger; +import io.mosip.authentication.core.util.CryptoUtil; +import io.mosip.kernel.core.logger.spi.Logger; +import io.mosip.kernel.core.util.StringUtils; +import net.minidev.json.JSONObject; + +/** + * The Class For VciExchangeRequestValidator extending the + * BaseAuthRequestValidator{@link BaseAuthRequestValidator}} + * + * @author Mahammed Taheer + * + * + */ + +@Component +public class VciExchangeRequestValidator extends AuthRequestValidator { + + /** The mosip logger. */ + private static Logger mosipLogger = IdaLogger.getLogger(VciExchangeRequestValidator.class); + + private static final ObjectMapper OBJECT_MAPPER; + + static { + OBJECT_MAPPER = new ObjectMapper(); + OBJECT_MAPPER.registerModule(new AfterburnerModule()); + } + + @Value("#{'${mosip.ida.vci.supported.cred.types:}'.split(',')}") + private List supportedCredTypes; + + /* + * (non-Javadoc) + * + * @see io.mosip.authentication.service.impl.indauth.validator. + * BaseAuthRequestValidator#supports(java.lang.Class) + */ + @Override + public boolean supports(Class clazz) { + return VciExchangeRequestDTO.class.equals(clazz); + } + + /* + * (non-Javadoc) + * + * @see io.mosip.authentication.service.impl.indauth.validator. + * BaseAuthRequestValidator#validate(java.lang.Object, + * org.springframework.validation.Errors) + */ + @Override + public void validate(Object target, Errors errors) { + VciExchangeRequestDTO vciExchangeRequestDTO = (VciExchangeRequestDTO) target; + if (vciExchangeRequestDTO != null) { + if (!errors.hasErrors()) { + validateReqTime(vciExchangeRequestDTO.getRequestTime(), errors, IdAuthCommonConstants.REQ_TIME); + } + + if (!errors.hasErrors()) { + validateTxnId(vciExchangeRequestDTO.getTransactionID(), errors, IdAuthCommonConstants.TRANSACTION_ID); + } + + if (!errors.hasErrors()) { + validateAuthToken(vciExchangeRequestDTO.getVcAuthToken(), errors, IdAuthCommonConstants.VC_AUTH_TOKEN); + } + + if (!errors.hasErrors()) { + validateCredSubjectId(vciExchangeRequestDTO.getCredSubjectId(), errors, IdAuthCommonConstants.CREDENTIAL_SUBJECT_ID); + } + + if (!errors.hasErrors()) { + validateCredSubjectIdDIDFormat(vciExchangeRequestDTO.getCredSubjectId(), errors, IdAuthCommonConstants.CREDENTIAL_SUBJECT_ID); + } + + if (!errors.hasErrors()) { + validateVCFormat(vciExchangeRequestDTO.getVcFormat(), errors, IdAuthCommonConstants.VC_FORMAT); + } + + if (!errors.hasErrors()) { + validateAllowedVCFormats(vciExchangeRequestDTO.getVcFormat(), errors, IdAuthCommonConstants.VC_FORMAT); + } + + if (!errors.hasErrors()) { + validateCredentialType(vciExchangeRequestDTO.getCredentialsDefinition().getType(), errors, IdAuthCommonConstants.VC_CREDENTIAL_TYPE); + } + + } else { + mosipLogger.error(IdAuthCommonConstants.SESSION_ID, this.getClass().getSimpleName(), IdAuthCommonConstants.VALIDATE, + IdAuthCommonConstants.INVALID_INPUT_PARAMETER + IdAuthCommonConstants.REQUEST); + errors.rejectValue(IdAuthCommonConstants.REQUEST, IdAuthenticationErrorConstants.UNABLE_TO_PROCESS.getErrorCode(), + String.format(IdAuthenticationErrorConstants.UNABLE_TO_PROCESS.getErrorMessage(), IdAuthCommonConstants.REQUEST)); + } + + } + + private void validateAuthToken(String kycToken, Errors errors, String paramName) { + + if (kycToken == null || StringUtils.isEmpty(kycToken.trim())) { + mosipLogger.error(SESSION_ID, this.getClass().getSimpleName(), VALIDATE, + MISSING_INPUT_PARAMETER + paramName); + errors.rejectValue(paramName, IdAuthenticationErrorConstants.MISSING_INPUT_PARAMETER.getErrorCode(), + new Object[] { paramName }, + IdAuthenticationErrorConstants.MISSING_INPUT_PARAMETER.getErrorMessage()); + } + } + + private void validateCredSubjectId(String credSubjectId, Errors errors, String paramName) { + if (credSubjectId == null || StringUtils.isEmpty(credSubjectId.trim())) { + mosipLogger.error(SESSION_ID, this.getClass().getSimpleName(), VALIDATE, + MISSING_INPUT_PARAMETER + paramName); + errors.rejectValue(paramName, IdAuthenticationErrorConstants.MISSING_INPUT_PARAMETER.getErrorCode(), + new Object[] { paramName }, + IdAuthenticationErrorConstants.MISSING_INPUT_PARAMETER.getErrorMessage()); + } + } + + private void validateVCFormat(String vcFormat, Errors errors, String paramName) { + if (vcFormat == null || StringUtils.isEmpty(vcFormat.trim())) { + mosipLogger.error(SESSION_ID, this.getClass().getSimpleName(), VALIDATE, + MISSING_INPUT_PARAMETER + paramName); + errors.rejectValue(paramName, IdAuthenticationErrorConstants.MISSING_INPUT_PARAMETER.getErrorCode(), + new Object[] { paramName }, + IdAuthenticationErrorConstants.MISSING_INPUT_PARAMETER.getErrorMessage()); + } + } + + private void validateCredentialType(List credentialType, Errors errors, String paramName) { + if (credentialType == null || credentialType.isEmpty()) { + mosipLogger.error(SESSION_ID, this.getClass().getSimpleName(), VALIDATE, + MISSING_INPUT_PARAMETER + paramName); + errors.rejectValue(paramName, IdAuthenticationErrorConstants.MISSING_INPUT_PARAMETER.getErrorCode(), + new Object[] { paramName }, + IdAuthenticationErrorConstants.MISSING_INPUT_PARAMETER.getErrorMessage()); + } else { + if(!supportedCredTypes.containsAll(credentialType)) { + mosipLogger.error(SESSION_ID, this.getClass().getSimpleName(), VALIDATE, + MISSING_INPUT_PARAMETER + paramName); + errors.rejectValue(paramName, IdAuthenticationErrorConstants.INVALID_INPUT_PARAMETER.getErrorCode(), + new Object[] { paramName }, + IdAuthenticationErrorConstants.INVALID_INPUT_PARAMETER.getErrorMessage()); + } + } + } + + private void validateCredSubjectIdDIDFormat(String credSubjectId, Errors errors, String paramName) { + String[] didArray = StringUtils.split(credSubjectId, COLON); + if (didArray.length != 3) { + mosipLogger.error(SESSION_ID, this.getClass().getSimpleName(), VALIDATE, + "Invalid DID Format input for credential subject ID: " + credSubjectId); + errors.rejectValue(paramName, IdAuthenticationErrorConstants.INVALID_INPUT_PARAMETER.getErrorCode(), + new Object[] { paramName }, + IdAuthenticationErrorConstants.INVALID_INPUT_PARAMETER.getErrorMessage()); + } else { + String identityJwk = new String(CryptoUtil.decodeBase64(didArray[2])); + try { + JSONObject jsonObject = OBJECT_MAPPER.readValue(identityJwk, JSONObject.class); + validatePublicKeyAttributes(jsonObject, errors, PUBLIC_KEY_EXPONENT_KEY); + validatePublicKeyAttributes(jsonObject, errors, PUBLIC_KEY_MODULUS_KEY); + } catch (IOException ioe) { + mosipLogger.error(SESSION_ID, this.getClass().getSimpleName(), VALIDATE, + "Error formating Identity JWK", ioe); + errors.rejectValue(paramName, IdAuthenticationErrorConstants.INVALID_INPUT_PARAMETER.getErrorCode(), + new Object[] { paramName }, + IdAuthenticationErrorConstants.INVALID_INPUT_PARAMETER.getErrorMessage()); + } + } + } + + private void validatePublicKeyAttributes(JSONObject jsonObject, Errors errors, String publicKeyAttribute) { + String value = jsonObject.getAsString(publicKeyAttribute); + if (value == null || StringUtils.isEmpty(value.trim())) { + mosipLogger.error(SESSION_ID, this.getClass().getSimpleName(), VALIDATE, MISSING_INPUT_PARAMETER + publicKeyAttribute); + errors.rejectValue(publicKeyAttribute, IdAuthenticationErrorConstants.MISSING_INPUT_PARAMETER.getErrorCode(), + new Object[] { publicKeyAttribute }, IdAuthenticationErrorConstants.MISSING_INPUT_PARAMETER.getErrorMessage()); + } + } + + private void validateAllowedVCFormats(String vcFormat, Errors errors, String paramName) { + boolean allowed = Stream.of(VCFormats.values()).filter(t -> t.getFormat().equalsIgnoreCase(vcFormat)).findAny().isPresent(); + if (!allowed) { + mosipLogger.error(SESSION_ID, this.getClass().getSimpleName(), VALIDATE, + "Not Supported VC Format: " + vcFormat); + errors.rejectValue(paramName, IdAuthenticationErrorConstants.INVALID_INPUT_PARAMETER.getErrorCode(), + new Object[] { paramName }, + IdAuthenticationErrorConstants.INVALID_INPUT_PARAMETER.getErrorMessage()); + } + } +} diff --git a/authentication/esignet-integration-impl/pom.xml b/authentication/esignet-integration-impl/pom.xml index 07767904c57..148d4dfcc50 100644 --- a/authentication/esignet-integration-impl/pom.xml +++ b/authentication/esignet-integration-impl/pom.xml @@ -31,11 +31,16 @@ 1.18.22 compile - + + io.mosip.esignet + esignet-core + 1.2.0-SNAPSHOT + provided + io.mosip.esignet esignet-integration-api - 1.0.0 + 1.2.0-SNAPSHOT provided @@ -63,5 +68,10 @@ ${jackson.version} test + + info.weboftrust + ld-signatures-java + 1.0.0 + diff --git a/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/dto/CredentialDefinitionDTO.java b/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/dto/CredentialDefinitionDTO.java new file mode 100644 index 00000000000..af7a0a38848 --- /dev/null +++ b/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/dto/CredentialDefinitionDTO.java @@ -0,0 +1,20 @@ +package io.mosip.authentication.esignet.integration.dto; + +import java.util.List; +import java.util.Map; + +import lombok.Data; + +@Data +public class CredentialDefinitionDTO { + + /** */ + private Map credentialSubject; + + /** */ + private List type; + + /** */ + private List context; + +} diff --git a/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/dto/IdaVcExchangeRequest.java b/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/dto/IdaVcExchangeRequest.java new file mode 100644 index 00000000000..62360a9b436 --- /dev/null +++ b/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/dto/IdaVcExchangeRequest.java @@ -0,0 +1,40 @@ +package io.mosip.authentication.esignet.integration.dto; + +import java.util.List; +import java.util.Map; + +import javax.validation.constraints.NotNull; +import lombok.Data; + +@Data +public class IdaVcExchangeRequest { + + @NotNull + private String vcAuthToken; + + /** The Variable to hold value of Credential Subject Id */ + @NotNull + private String credSubjectId; + + /** The Variable to hold value of VC Format type */ + @NotNull + private String vcFormat; + + /** The Variable to hold value of list of user selected locales */ + private List locales; + + private Map metadata; + + private String id; + + private String version; + + private String individualId; + + private String transactionID; + + private String requestTime; + + private CredentialDefinitionDTO credentialsDefinition; + +} diff --git a/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/dto/IdaVcExchangeResponse.java b/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/dto/IdaVcExchangeResponse.java new file mode 100644 index 00000000000..7d3b9d97699 --- /dev/null +++ b/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/dto/IdaVcExchangeResponse.java @@ -0,0 +1,9 @@ +package io.mosip.authentication.esignet.integration.dto; + +import lombok.Data; + +@Data +public class IdaVcExchangeResponse { + + private T verifiableCredentials; +} diff --git a/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/helper/VCITransactionHelper.java b/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/helper/VCITransactionHelper.java new file mode 100644 index 00000000000..feba8d8a252 --- /dev/null +++ b/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/helper/VCITransactionHelper.java @@ -0,0 +1,30 @@ +package io.mosip.authentication.esignet.integration.helper; + +import java.util.Map; + +import io.mosip.esignet.core.dto.OIDCTransaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.CacheManager; +import org.springframework.stereotype.Component; + +@Component +public class VCITransactionHelper { + + @Autowired + CacheManager cacheManager; + + @Value("${mosip.esignet.ida.vci-user-info-cache}") + private String userinfoCache; + + @SuppressWarnings("unchecked") + public OIDCTransaction getOAuthTransaction(String accessTokenHash) throws Exception { + if (cacheManager.getCache(userinfoCache) != null) { + return cacheManager.getCache(userinfoCache).get(accessTokenHash, OIDCTransaction.class); + } + throw new Exception("cache_missing"); + } + + + +} diff --git a/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/service/IdaAuthenticatorImpl.java b/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/service/IdaAuthenticatorImpl.java index 23c91a36c1c..0b6597853d2 100644 --- a/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/service/IdaAuthenticatorImpl.java +++ b/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/service/IdaAuthenticatorImpl.java @@ -165,7 +165,11 @@ public KycExchangeResult doKycExchange(String relyingPartyId, String clientId, K idaKycExchangeRequest.setRequestTime(HelperService.getUTCDateTime()); idaKycExchangeRequest.setTransactionID(kycExchangeDto.getTransactionId()); idaKycExchangeRequest.setKycToken(kycExchangeDto.getKycToken()); - idaKycExchangeRequest.setConsentObtained(kycExchangeDto.getAcceptedClaims()); + if (!CollectionUtils.isEmpty(kycExchangeDto.getAcceptedClaims())) { + idaKycExchangeRequest.setConsentObtained(kycExchangeDto.getAcceptedClaims()); + } else { + idaKycExchangeRequest.setConsentObtained(List.of("sub")); + } idaKycExchangeRequest.setLocales(Arrays.asList(kycExchangeDto.getClaimsLocales())); idaKycExchangeRequest.setRespType(kycExchangeDto.getUserInfoResponseType()); //may be either JWT or JWE idaKycExchangeRequest.setIndividualId(kycExchangeDto.getIndividualId()); diff --git a/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/service/IdaVCIssuancePluginImpl.java b/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/service/IdaVCIssuancePluginImpl.java new file mode 100644 index 00000000000..17dc618d123 --- /dev/null +++ b/authentication/esignet-integration-impl/src/main/java/io/mosip/authentication/esignet/integration/service/IdaVCIssuancePluginImpl.java @@ -0,0 +1,212 @@ +package io.mosip.authentication.esignet.integration.service; + +import java.security.Key; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.*; + +import javax.crypto.Cipher; + +import io.mosip.authentication.esignet.integration.dto.IdaVcExchangeResponse; +import io.mosip.esignet.core.dto.OIDCTransaction; +import org.apache.commons.lang3.NotImplementedException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import foundation.identity.jsonld.JsonLDObject; +import io.mosip.authentication.esignet.integration.dto.IdaResponseWrapper; +import io.mosip.authentication.esignet.integration.dto.IdaVcExchangeRequest; +import io.mosip.authentication.esignet.integration.dto.CredentialDefinitionDTO; +import io.mosip.authentication.esignet.integration.helper.VCITransactionHelper; +import io.mosip.esignet.api.dto.VCRequestDto; +import io.mosip.esignet.api.dto.VCResult; +import io.mosip.esignet.api.spi.VCIssuancePlugin; +import io.mosip.kernel.core.keymanager.spi.KeyStore; +import io.mosip.kernel.keymanagerservice.constant.KeymanagerConstant; +import io.mosip.kernel.keymanagerservice.entity.KeyAlias; +import io.mosip.kernel.keymanagerservice.helper.KeymanagerDBHelper; +import lombok.extern.slf4j.Slf4j; + +@Component +@Slf4j +@ConditionalOnProperty(value = "mosip.esignet.integration.vci-plugin", havingValue = "IdaVCIssuancePluginImpl") +public class IdaVCIssuancePluginImpl implements VCIssuancePlugin { + private static final String CLIENT_ID = "client_id"; + private static final String RELYING_PARTY_ID = "relyingPartyId"; + private static final String ACCESS_TOKEN_HASH = "accessTokenHash"; + private static final String INDIVIDUAL_ID = "individualId"; + private static final String KYC_TOKEN = "kycToken"; + private static final String AUTH_TRANSACTION_ID = "authTransactionId"; + public static final String SIGNATURE_HEADER_NAME = "signature"; + public static final String AUTHORIZATION_HEADER_NAME = "Authorization"; + public static final String OIDC_SERVICE_APP_ID = "OIDC_SERVICE"; + public static final String AES_CIPHER_FAILED = "aes_cipher_failed"; + public static final String NO_UNIQUE_ALIAS = "no_unique_alias"; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private RestTemplate restTemplate; + + @Autowired + HelperService helperService; + + @Autowired + private KeyStore keyStore; + + @Autowired + private KeymanagerDBHelper dbHelper; + + @Autowired + VCITransactionHelper vciTransactionHelper; + + @Value("${mosip.esignet.ida.vci-exchange-url}") + private String vciExchangeUrl; + + @Value("${mosip.esignet.ida.vci-exchange-id}") + private String vciExchangeId; + + @Value("${mosip.esignet.ida.vci-exchange-version}") + private String vciExchangeVersion; + + @Value("${mosip.esignet.cache.secure.individual-id}") + private boolean secureIndividualId; + + @Value("${mosip.esignet.cache.store.individual-id}") + private boolean storeIndividualId; + + @Value("${mosip.esignet.cache.security.algorithm-name}") + private String aesECBTransformation; + + @Value("${mosip.esignet.cache.security.secretkey.reference-id}") + private String cacheSecretKeyRefId; + + private Base64.Decoder urlSafeDecoder = Base64.getUrlDecoder(); + + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public VCResult getVerifiableCredentialWithLinkedDataProof(VCRequestDto vcRequestDto, String holderId, + Map identityDetails) { + log.info("Started to created the VCIssuance"); + try { + OIDCTransaction transaction = vciTransactionHelper + .getOAuthTransaction(identityDetails.get(ACCESS_TOKEN_HASH).toString()); + String individualId = getIndividualId(transaction.getIndividualId()); + IdaVcExchangeRequest idaVciExchangeRequest = new IdaVcExchangeRequest(); + CredentialDefinitionDTO vciCred = new CredentialDefinitionDTO(); + idaVciExchangeRequest.setId(vciExchangeId);// Configuration + idaVciExchangeRequest.setVersion(vciExchangeVersion);// Configuration + idaVciExchangeRequest.setRequestTime(HelperService.getUTCDateTime()); + idaVciExchangeRequest.setTransactionID(transaction.getAuthTransactionId());// Cache input + idaVciExchangeRequest.setVcAuthToken(transaction.getKycToken()); // Cache input + idaVciExchangeRequest.setIndividualId(individualId); + idaVciExchangeRequest.setCredSubjectId(holderId); + idaVciExchangeRequest.setVcFormat(vcRequestDto.getFormat()); + idaVciExchangeRequest.setLocales(transaction.getClaimsLocales() != null ? + Arrays.asList(transaction.getClaimsLocales()) : List.of("eng")); + vciCred.setCredentialSubject(vcRequestDto.getCredentialSubject()); + vciCred.setType(vcRequestDto.getType()); + vciCred.setContext(vcRequestDto.getContext()); + idaVciExchangeRequest.setCredentialsDefinition(vciCred); + + String requestBody = objectMapper.writeValueAsString(idaVciExchangeRequest); + RequestEntity requestEntity = RequestEntity + .post(UriComponentsBuilder.fromUriString(vciExchangeUrl) + .pathSegment(transaction.getRelyingPartyId(), + identityDetails.get(CLIENT_ID).toString()) + .build().toUri()) + .contentType(MediaType.APPLICATION_JSON_UTF8) + .header(SIGNATURE_HEADER_NAME, helperService.getRequestSignature(requestBody)) + .header(AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_NAME).body(requestBody); + + switch (vcRequestDto.getFormat()) { + case "ldp_vc": + ResponseEntity>> responseEntity = restTemplate.exchange(requestEntity, + new ParameterizedTypeReference>>() { + }); + return getLinkedDataProofCredential(responseEntity); + default: + log.error("Errors in response received from IDA VCI Exchange: {}"); + break; + } + } catch (Exception e) { + log.error("IDA Vci-exchange failed ", e); + } + return null; + + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public VCResult getLinkedDataProofCredential(ResponseEntity>> responseEntity) { + if (responseEntity.getStatusCode().is2xxSuccessful() && responseEntity.getBody() != null) { + IdaResponseWrapper> responseWrapper = responseEntity.getBody(); + if (responseWrapper.getResponse() != null) { + VCResult vCResult = new VCResult(); + vCResult.setCredential(responseWrapper.getResponse().getVerifiableCredentials()); + vCResult.setFormat("ldp_vc"); + return vCResult; + } + log.error("Errors in response received from IDA VC Exchange: {}", responseWrapper.getErrors()); + } + return null; + } + + @Override + public VCResult getVerifiableCredential(VCRequestDto vcRequestDto, String holderId, + Map identityDetails) { + throw new NotImplementedException("This method is not implemented"); + } + + protected String getIndividualId(String encryptedIndividualId) throws Exception { + if (!storeIndividualId) + return null; + return secureIndividualId ? decryptIndividualId(encryptedIndividualId) : encryptedIndividualId; + } + + private String decryptIndividualId(String encryptedIndividualId) throws Exception { + try { + Cipher cipher = Cipher.getInstance(aesECBTransformation); + byte[] decodedBytes = b64Decode(encryptedIndividualId); + cipher.init(Cipher.DECRYPT_MODE, getSecretKeyFromHSM()); + return new String(cipher.doFinal(decodedBytes, 0, decodedBytes.length)); + } catch (Exception e) { + log.error("Error Cipher Operations of provided secret data.", e); + throw new Exception(AES_CIPHER_FAILED); + } + } + + private Key getSecretKeyFromHSM() throws Exception { + String keyAlias = getKeyAlias(OIDC_SERVICE_APP_ID, cacheSecretKeyRefId); + if (Objects.nonNull(keyAlias)) { + return keyStore.getSymmetricKey(keyAlias); + } + throw new Exception(NO_UNIQUE_ALIAS); + } + + private String getKeyAlias(String keyAppId, String keyRefId) throws Exception { + Map> keyAliasMap = dbHelper.getKeyAliases(keyAppId, keyRefId, + LocalDateTime.now(ZoneOffset.UTC)); + List currentKeyAliases = keyAliasMap.get(KeymanagerConstant.CURRENTKEYALIAS); + if (!currentKeyAliases.isEmpty() && currentKeyAliases.size() == 1) { + return currentKeyAliases.get(0).getAlias(); + } + log.error("CurrentKeyAlias is not unique. KeyAlias count: {}", currentKeyAliases.size()); + throw new Exception(NO_UNIQUE_ALIAS); + } + + private byte[] b64Decode(String value) { + return urlSafeDecoder.decode(value); + } +} diff --git a/authentication/esignet-integration-impl/src/test/java/io/mosip/authentication/esignet/integration/service/IdaAuthenticatorImplTest.java b/authentication/esignet-integration-impl/src/test/java/io/mosip/authentication/esignet/integration/service/IdaAuthenticatorImplTest.java index f0f68e4be7a..cad47ce0a5a 100644 --- a/authentication/esignet-integration-impl/src/test/java/io/mosip/authentication/esignet/integration/service/IdaAuthenticatorImplTest.java +++ b/authentication/esignet-integration-impl/src/test/java/io/mosip/authentication/esignet/integration/service/IdaAuthenticatorImplTest.java @@ -248,6 +248,41 @@ public void doKycExchange_withValidDetails_thenPass() throws Exception { Assert.assertEquals(idaKycExchangeResponse.getEncryptedKyc(), kycExchangeResult.getEncryptedKyc()); } + + @Test + public void doKycExchange_withValidDetailsEmptyAcceptedClaims_thenPass() throws Exception { + KycExchangeDto kycExchangeDto = new KycExchangeDto(); + kycExchangeDto.setIndividualId("IND1234"); + kycExchangeDto.setKycToken("KYCT123"); + kycExchangeDto.setTransactionId("TRAN123"); + List acceptedClaims = List.of(); + kycExchangeDto.setAcceptedClaims(acceptedClaims); + String[] claimsLacales = new String[] { "claims", "locales" }; + kycExchangeDto.setClaimsLocales(claimsLacales); + + Mockito.when(mapper.writeValueAsString(Mockito.any())).thenReturn("value"); + + IdaKycExchangeResponse idaKycExchangeResponse = new IdaKycExchangeResponse(); + idaKycExchangeResponse.setEncryptedKyc("ENCRKYC123"); + + IdaResponseWrapper idaResponseWrapper = new IdaResponseWrapper<>(); + idaResponseWrapper.setResponse(idaKycExchangeResponse); + idaResponseWrapper.setTransactionID("TRAN123"); + idaResponseWrapper.setVersion("VER1"); + + ResponseEntity> responseEntity = new ResponseEntity>( + idaResponseWrapper, HttpStatus.OK); + + Mockito.when(restTemplate.exchange(Mockito.>any(), + Mockito.>>any())) + .thenReturn(responseEntity); + + KycExchangeResult kycExchangeResult = idaAuthenticatorImpl.doKycExchange("relyingPartyId", "clientId", + kycExchangeDto); + + Assert.assertEquals(idaKycExchangeResponse.getEncryptedKyc(), kycExchangeResult.getEncryptedKyc()); + } + @Test public void doKycExchange_withInvalidDetails_thenFail() throws Exception { KycExchangeDto kycExchangeDto = new KycExchangeDto(); diff --git a/authentication/pom.xml b/authentication/pom.xml index 92ff663d80d..5d9d748d968 100644 --- a/authentication/pom.xml +++ b/authentication/pom.xml @@ -54,6 +54,10 @@ false + + danubetech-maven-public + https://repo.danubetech.com/repository/maven-public/ + @@ -91,7 +95,7 @@ 1.2.0.1-B1 ${kernel.parent.version} - 1.2.0.1-B2 + 1.2.0.1-B3-SNAPSHOT ${kernel.parent.version} ${kernel.parent.version} ${kernel.parent.version} @@ -101,7 +105,7 @@ ${kernel.parent.version} ${kernel.parent.version} ${kernel.parent.version} - ${kernel.parent.version} + 1.2.1-SNAPSHOT ${kernel.parent.version} ${kernel.parent.version} 1.2.0.1-B1 @@ -157,6 +161,7 @@ 3.1 1.5.10 + diff --git a/db_scripts/mosip_ida/ddl/ida-cred_subject_id_store.sql b/db_scripts/mosip_ida/ddl/ida-cred_subject_id_store.sql new file mode 100644 index 00000000000..355d7276782 --- /dev/null +++ b/db_scripts/mosip_ida/ddl/ida-cred_subject_id_store.sql @@ -0,0 +1,32 @@ +CREATE TABLE ida.cred_subject_id_store( + id character varying(36) NOT NULL, + id_vid_hash character varying(128) NOT NULL, + token_id character varying(128) NOT NULL, + cred_subject_id character varying(2000) NOT NULL, + csid_key_hash character varying(128) NOT NULL, + oidc_client_id character varying(128), + csid_status character varying(36), + cr_by character varying(256) NOT NULL, + cr_dtimes timestamp NOT NULL, + upd_by character varying(256), + upd_dtimes timestamp, + is_deleted boolean DEFAULT FALSE, + del_dtimes timestamp, + CONSTRAINT key_hash_unique UNIQUE (id_vid_hash, csid_key_hash) +); +COMMENT ON TABLE ida.cred_subject_id_store IS 'Credential Subject Id Store: To store and maintain the input credential subject ids to identify the individual.'; +COMMENT ON COLUMN ida.cred_subject_id_store.id IS 'ID: Id is a unique identifier (UUID) used to map uniqueness to the credential subject id.'; +COMMENT ON COLUMN ida.cred_subject_id_store.id_vid_hash IS 'IdVidHash: SHA 256 Hash value of the Id/VID.'; +COMMENT ON COLUMN ida.cred_subject_id_store.token_id IS 'Token ID: Token ID generated in reference to UIN/VID'; +COMMENT ON COLUMN ida.cred_subject_id_store.cred_subject_id IS 'Credential Subject ID : DID format holder id.'; +COMMENT ON COLUMN ida.cred_subject_id_store.csid_key_hash IS 'Credential Subject ID Public Key Hash: Derived hash value of the public key.'; +COMMENT ON COLUMN ida.cred_subject_id_store.oidc_client_id IS 'OIDC Client ID: An Id assigned to specific OIDC Client.'; +COMMENT ON COLUMN ida.cred_subject_id_store.csid_status IS 'Credential Subject Id Status: To identify the current status of the credential subject id.'; +COMMENT ON COLUMN ida.cred_subject_id_store.cr_by IS 'Created By : ID or name of the user who create / insert record'; +COMMENT ON COLUMN ida.cred_subject_id_store.cr_dtimes IS 'Created DateTimestamp : Date and Timestamp when the record is created/inserted'; +COMMENT ON COLUMN ida.cred_subject_id_store.upd_by IS 'Updated By : ID or name of the user who update the record with new values'; +COMMENT ON COLUMN ida.cred_subject_id_store.upd_dtimes IS 'Updated DateTimestamp : Date and Timestamp when any of the fields in the record is updated with new values.'; +COMMENT ON COLUMN ida.cred_subject_id_store.is_deleted IS 'IS_Deleted : Flag to mark whether the record is Soft deleted.'; +COMMENT ON COLUMN ida.cred_subject_id_store.del_dtimes IS 'Deleted DateTimestamp : Date and Timestamp when the record is soft deleted with is_deleted=TRUE'; + +CREATE INDEX ind_csid_key_hash ON ida.cred_subject_id_store (csid_key_hash); \ No newline at end of file diff --git a/db_scripts/mosip_ida/dml/ida-key_policy_def.csv b/db_scripts/mosip_ida/dml/ida-key_policy_def.csv index 7e807a194be..f370690ba33 100644 --- a/db_scripts/mosip_ida/dml/ida-key_policy_def.csv +++ b/db_scripts/mosip_ida/dml/ida-key_policy_def.csv @@ -3,4 +3,5 @@ IDA,1095,TRUE,mosipadmin,now(),60,NA ROOT,1826,TRUE,mosipadmin,now(),90,NA BASE,730,TRUE,mosipadmin,now(),30,NA IDA_KEY_BINDING,1095,TRUE,mosipadmin,now(),60,NA -IDA_KYC_EXCHANGE,1095,TRUE,mosipadmin,now(),60,NA \ No newline at end of file +IDA_KYC_EXCHANGE,1095,TRUE,mosipadmin,now(),60,NA +IDA_VCI_EXCHANGE,1095,TRUE,mosipadmin,now(),60,NA \ No newline at end of file diff --git a/db_upgrade_scripts/mosip_ida/sql/1.2.0.1-B4_to_1.2.0.1-B5_rollback.sql b/db_upgrade_scripts/mosip_ida/sql/1.2.0.1-B4_to_1.2.0.1-B5_rollback.sql new file mode 100644 index 00000000000..cb5727f8853 --- /dev/null +++ b/db_upgrade_scripts/mosip_ida/sql/1.2.0.1-B4_to_1.2.0.1-B5_rollback.sql @@ -0,0 +1,7 @@ +\echo 'Upgrade Queries not required for transition from $CURRENT_VERSION to $UPGRADE_VERSION' + +DROP TABLE IF EXISTS ida.cred_subject_id_store CASCADE; + +DROP INDEX IF EXISTS ida.ind_csid_key_hash; + +DELETE FROM ida.key_policy_def WHERE app_id='IDA_VCI_EXCHANGE'; \ No newline at end of file diff --git a/db_upgrade_scripts/mosip_ida/sql/1.2.0.1-B4_to_1.2.0.1-B5_upgrade.sql b/db_upgrade_scripts/mosip_ida/sql/1.2.0.1-B4_to_1.2.0.1-B5_upgrade.sql new file mode 100644 index 00000000000..efb74c3babe --- /dev/null +++ b/db_upgrade_scripts/mosip_ida/sql/1.2.0.1-B4_to_1.2.0.1-B5_upgrade.sql @@ -0,0 +1,47 @@ +-- ------------------------------------------------------------------------------------------------- +-- Database Name : mosip_ida +-- Release Version : 1.2.1 +-- Purpose : Database Alter scripts for the release for ID Authentication DB. +-- Create By : Mahammed Taheer +-- Created Date : Aug-2023 +-- +-- Modified Date Modified By Comments / Remarks +-- ------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +\c mosip_ida sysadmin + +CREATE TABLE ida.cred_subject_id_store( + id character varying(36) NOT NULL, + id_vid_hash character varying(128) NOT NULL, + token_id character varying(128) NOT NULL, + cred_subject_id character varying(2000) NOT NULL, + csid_key_hash character varying(128) NOT NULL, + oidc_client_id character varying(128), + csid_status character varying(36), + cr_by character varying(256) NOT NULL, + cr_dtimes timestamp NOT NULL, + upd_by character varying(256), + upd_dtimes timestamp, + is_deleted boolean DEFAULT FALSE, + del_dtimes timestamp, + CONSTRAINT key_hash_unique UNIQUE (id_vid_hash, csid_key_hash) +); +COMMENT ON TABLE ida.cred_subject_id_store IS 'Credential Subject Id Store: To store and maintain the input credential subject ids to identify the individual.'; +COMMENT ON COLUMN ida.cred_subject_id_store.id IS 'ID: Id is a unique identifier (UUID) used to map uniqueness to the credential subject id.'; +COMMENT ON COLUMN ida.cred_subject_id_store.id_vid_hash IS 'IdVidHash: SHA 256 Hash value of the Id/VID.'; +COMMENT ON COLUMN ida.cred_subject_id_store.token_id IS 'Token ID: Token ID generated in reference to UIN/VID'; +COMMENT ON COLUMN ida.cred_subject_id_store.cred_subject_id IS 'Credential Subject ID : DID format holder id.'; +COMMENT ON COLUMN ida.cred_subject_id_store.csid_key_hash IS 'Credential Subject ID Public Key Hash: Derived hash value of the public key.'; +COMMENT ON COLUMN ida.cred_subject_id_store.oidc_client_id IS 'OIDC Client ID: An Id assigned to specific OIDC Client.'; +COMMENT ON COLUMN ida.cred_subject_id_store.csid_status IS 'Credential Subject Id Status: To identify the current status of the credential subject id.'; +COMMENT ON COLUMN ida.cred_subject_id_store.cr_by IS 'Created By : ID or name of the user who create / insert record'; +COMMENT ON COLUMN ida.cred_subject_id_store.cr_dtimes IS 'Created DateTimestamp : Date and Timestamp when the record is created/inserted'; +COMMENT ON COLUMN ida.cred_subject_id_store.upd_by IS 'Updated By : ID or name of the user who update the record with new values'; +COMMENT ON COLUMN ida.cred_subject_id_store.upd_dtimes IS 'Updated DateTimestamp : Date and Timestamp when any of the fields in the record is updated with new values.'; +COMMENT ON COLUMN ida.cred_subject_id_store.is_deleted IS 'IS_Deleted : Flag to mark whether the record is Soft deleted.'; +COMMENT ON COLUMN ida.cred_subject_id_store.del_dtimes IS 'Deleted DateTimestamp : Date and Timestamp when the record is soft deleted with is_deleted=TRUE'; + +CREATE INDEX ind_csid_key_hash ON ida.cred_subject_id_store (csid_key_hash); + +INSERT INTO ida.key_policy_def (app_id, key_validity_duration, is_active, cr_by, cr_dtimes, upd_by, upd_dtimes, is_deleted, del_dtimes, pre_expire_days, access_allowed) +VALUES('IDA_VCI_EXCHANGE', 1095, true, 'mosipadmin', now(), NULL, NULL, false, NULL, 60, 'NA'); \ No newline at end of file