diff --git a/.github/workflows/push-trigger.yml b/.github/workflows/push-trigger.yml index f331ae15..03a3f597 100644 --- a/.github/workflows/push-trigger.yml +++ b/.github/workflows/push-trigger.yml @@ -123,7 +123,7 @@ jobs: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_INJI_TEAM }} build-maven-apitest-mimoto: - uses: mosip/kattu/.github/workflows/maven-build.yml@master-java21 + uses: mosip/kattu/.github/workflows/maven-build.yml@master with: SERVICE_LOCATION: ./apitest BUILD_ARTIFACT: apitest-mimoto @@ -137,7 +137,7 @@ jobs: publish_to_nexus_apitest_mimoto: if: "${{ !contains(github.ref, 'master') && github.event_name != 'pull_request' && github.event_name != 'release' && github.event_name != 'prerelease' && github.event_name != 'publish' }}" needs: build-maven-apitest-mimoto - uses: mosip/kattu/.github/workflows/maven-publish-to-nexus.yml@master-java21 + uses: mosip/kattu/.github/workflows/maven-publish-to-nexus.yml@master with: SERVICE_LOCATION: ./apitest secrets: @@ -157,12 +157,12 @@ jobs: SERVICE_LOCATION: apitest BUILD_ARTIFACT: apitest-mimoto-local steps: - - uses: actions/checkout@v3 - - name: Set up JDK 21 - uses: actions/setup-java@v3 + - uses: actions/checkout@v2 + - name: Set up JDK 11 + uses: actions/setup-java@v1 with: - distribution: 'temurin' - java-version: '21' + 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 the settings file for ossrh server @@ -205,7 +205,7 @@ jobs: ONLY_DOCKER: true fail-fast: false name: ${{ matrix.SERVICE_NAME }} - uses: mosip/kattu/.github/workflows/docker-build.yml@master-java21 + uses: mosip/kattu/.github/workflows/docker-build.yml@master with: SERVICE_LOCATION: ${{ matrix.SERVICE_LOCATION }} SERVICE_NAME: ${{ matrix.SERVICE_NAME }} @@ -217,10 +217,11 @@ jobs: RELEASE_DOCKER_HUB: ${{ secrets.RELEASE_DOCKER_HUB }} SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_INJI_TEAM }} +# Commenting out sonar check for api test as it will not work on JDK-11 # sonar_analysis_apitest_mimoto: # needs: build-maven-apitest-mimoto # if: "${{ github.event_name != 'pull_request' }}" -# uses: mosip/kattu/.github/workflows/maven-sonar-analysis.yml@master-java21 +# uses: mosip/kattu/.github/workflows/maven-sonar-analysis.yml@master # with: # SERVICE_LOCATION: ./apitest # secrets: diff --git a/apitest/Dockerfile b/apitest/Dockerfile index 5dea0ddb..8ab86853 100644 --- a/apitest/Dockerfile +++ b/apitest/Dockerfile @@ -1,4 +1,4 @@ -FROM mosipdev/openjdk-21-jre:latest +FROM openjdk:11 ARG SOURCE ARG COMMIT_HASH @@ -23,33 +23,32 @@ ARG container_user_gid=1001 ARG KUBECTL_VERSION=1.22.9 -# set working directory for the user WORKDIR /home/${container_user} ENV work_dir=/home/${container_user} -# Combine all necessary files into a single COPY command COPY ./apitest/target $work_dir/ COPY application.properties $work_dir/ COPY ["Biometric Devices", "$work_dir/Biometric Devices"] COPY ["resource", "$work_dir/resource"] COPY entrypoint.sh $work_dir -# install packages and create user -RUN apt-get -y update \ -&& apt-get install -y unzip jq curl \ -&& groupadd -g ${container_user_gid} ${container_user_group} \ -&& useradd -u ${container_user_uid} -g ${container_user_group} -s /bin/bash -m ${container_user} \ -&& curl -LO "https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VERSION}/bin/linux/amd64/kubectl" \ -&& mkdir -p /home/${container_user} \ -&& chmod +x kubectl $work_dir/entrypoint.sh \ -&& mv kubectl /usr/local/bin/ \ -&& chown -R ${container_user}:${container_user} /home/${container_user} /etc/ssl/certs/java/cacerts \ -&& chmod 644 /etc/ssl/certs/java/cacerts - -# select container user for all tasks +RUN apt-get -y update && \ + apt-get install -y unzip jq && \ + groupadd -g ${container_user_gid} ${container_user_group} && \ + useradd -u ${container_user_uid} -g ${container_user_group} -s /bin/sh -m ${container_user} && \ + curl -LO "https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VERSION}/bin/linux/amd64/kubectl" && \ + chmod +x kubectl && \ + mv kubectl /usr/local/bin/ && \ + chown -R ${container_user}:${container_user} /home/${container_user} /usr/local/openjdk-11/lib/security/cacerts && \ + chmod 644 /usr/local/openjdk-11/lib/security/cacerts && \ + chmod +x $work_dir/entrypoint.sh + + USER ${container_user_uid}:${container_user_gid} +WORKDIR ${work_dir} + EXPOSE 8083 ENV MODULES= @@ -57,4 +56,4 @@ ENV ENV_USER= ENV ENV_ENDPOINT= ENV ENV_TESTLEVEL=smokeAndRegression -ENTRYPOINT ["./entrypoint.sh"] +ENTRYPOINT ["./entrypoint.sh"] \ No newline at end of file diff --git a/apitest/pom.xml b/apitest/pom.xml index f253133b..f22110e9 100644 --- a/apitest/pom.xml +++ b/apitest/pom.xml @@ -8,7 +8,7 @@ apitest-mimoto Parent project of apitest-mimoto https://github.com/mosip/mimoto - 1.2.1-java21-SNAPSHOT + 0.13.0-SNAPSHOT @@ -37,8 +37,8 @@ UTF-8 - 21 - 21 + 11 + 11 3.8.0 3.0.2 3.1.0 @@ -49,14 +49,14 @@ 2.2.1 3.0.1 - apitest-mimoto-1.2.1-java21-SNAPSHOT-jar-with-dependencies + apitest-mimoto-0.13.0-SNAPSHOT-jar-with-dependencies io.mosip.testrig.apirig.apitest.commons apitest-commons - 1.2.1-java21-SNAPSHOT + 1.2.1 diff --git a/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/AddIdentity.java b/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/AddIdentity.java index 585132dd..dd8820bf 100644 --- a/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/AddIdentity.java +++ b/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/AddIdentity.java @@ -34,6 +34,7 @@ import io.mosip.testrig.apirig.utils.ConfigManager; import io.mosip.testrig.apirig.utils.GlobalConstants; import io.mosip.testrig.apirig.utils.KernelAuthentication; +import io.mosip.testrig.apirig.utils.MimotoUtil; import io.mosip.testrig.apirig.utils.OutputValidationUtil; import io.mosip.testrig.apirig.utils.ReportUtil; import io.mosip.testrig.apirig.utils.RestClient; @@ -97,7 +98,7 @@ public void test(TestCaseDTO testCaseDTO) throws AuthenticationTestException, Ad new KernelAuthentication().getTokenByRole(testCaseDTO.getRole())).asString(), "response.uin"); - testCaseName = isTestCaseValidForExecution(testCaseDTO); + testCaseName = MimotoUtil.isTestCaseValidForExecution(testCaseDTO); DateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmmss"); Calendar cal = Calendar.getInstance(); diff --git a/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/DeleteWithParam.java b/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/DeleteWithParam.java index de59b212..b8835609 100644 --- a/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/DeleteWithParam.java +++ b/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/DeleteWithParam.java @@ -28,6 +28,7 @@ import io.mosip.testrig.apirig.utils.AuthenticationTestException; import io.mosip.testrig.apirig.utils.ConfigManager; import io.mosip.testrig.apirig.utils.GlobalConstants; +import io.mosip.testrig.apirig.utils.MimotoUtil; import io.mosip.testrig.apirig.utils.OutputValidationUtil; import io.mosip.testrig.apirig.utils.ReportUtil; import io.restassured.response.Response; @@ -77,7 +78,7 @@ public Object[] getTestCaseList(ITestContext context) { @Test(dataProvider = "testcaselist") public void test(TestCaseDTO testCaseDTO) throws AuthenticationTestException, AdminTestException { testCaseName = testCaseDTO.getTestCaseName(); - testCaseName = isTestCaseValidForExecution(testCaseDTO); + testCaseName = MimotoUtil.isTestCaseValidForExecution(testCaseDTO); if (HealthChecker.signalTerminateExecution) { throw new SkipException( GlobalConstants.TARGET_ENV_HEALTH_CHECK_FAILED + HealthChecker.healthCheckFailureMapS); diff --git a/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/GetWithParam.java b/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/GetWithParam.java index 308c7139..f3115155 100644 --- a/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/GetWithParam.java +++ b/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/GetWithParam.java @@ -30,6 +30,7 @@ import io.mosip.testrig.apirig.utils.AuthenticationTestException; import io.mosip.testrig.apirig.utils.ConfigManager; import io.mosip.testrig.apirig.utils.GlobalConstants; +import io.mosip.testrig.apirig.utils.MimotoUtil; import io.mosip.testrig.apirig.utils.OutputValidationUtil; import io.mosip.testrig.apirig.utils.ReportUtil; import io.restassured.response.Response; @@ -82,7 +83,7 @@ public Object[] getTestCaseList(ITestContext context) { @Test(dataProvider = "testcaselist") public void test(TestCaseDTO testCaseDTO) throws AuthenticationTestException, AdminTestException { testCaseName = testCaseDTO.getTestCaseName(); - testCaseName = isTestCaseValidForExecution(testCaseDTO); + testCaseName = MimotoUtil.isTestCaseValidForExecution(testCaseDTO); if (HealthChecker.signalTerminateExecution) { throw new SkipException( GlobalConstants.TARGET_ENV_HEALTH_CHECK_FAILED + HealthChecker.healthCheckFailureMapS); diff --git a/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/PostWithAutogenIdWithOtpGenerate.java b/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/PostWithAutogenIdWithOtpGenerate.java index 29eab140..6e670fc4 100644 --- a/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/PostWithAutogenIdWithOtpGenerate.java +++ b/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/PostWithAutogenIdWithOtpGenerate.java @@ -29,6 +29,7 @@ import io.mosip.testrig.apirig.utils.AuthenticationTestException; import io.mosip.testrig.apirig.utils.ConfigManager; import io.mosip.testrig.apirig.utils.GlobalConstants; +import io.mosip.testrig.apirig.utils.MimotoUtil; import io.mosip.testrig.apirig.utils.OutputValidationUtil; import io.mosip.testrig.apirig.utils.ReportUtil; import io.restassured.response.Response; @@ -95,7 +96,7 @@ public void test(TestCaseDTO testCaseDTO) throw new SkipException(GlobalConstants.VID_FEATURE_NOT_SUPPORTED); } } - testCaseName = isTestCaseValidForExecution(testCaseDTO); + testCaseName = MimotoUtil.isTestCaseValidForExecution(testCaseDTO); JSONObject req = new JSONObject(testCaseDTO.getInput()); auditLogCheck = testCaseDTO.isAuditLogCheck(); @@ -184,8 +185,13 @@ public void test(TestCaseDTO testCaseDTO) throw new SkipException("esignet is not deployed hence skipping the testcase"); } String tempUrl = ConfigManager.getEsignetBaseUrl(); + String inputJson = getJsonFromTemplate(testCaseDTO.getInput(), testCaseDTO.getInputTemplate()); + inputJson = inputJsonKeyWordHandeler(inputJson, testCaseName); + inputJson = MimotoUtil.getOTPFromSMTP(inputJson, testCaseDTO); + + response = postRequestWithCookieAuthHeaderAndXsrfTokenForAutoGenId(tempUrl + testCaseDTO.getEndPoint(), - getJsonFromTemplate(testCaseDTO.getInput(), testCaseDTO.getInputTemplate()), COOKIENAME, + inputJson, COOKIENAME, testCaseDTO.getTestCaseName(), idKeyName); } else { response = postWithBodyAndCookieForAutoGeneratedId(ApplnURI + testCaseDTO.getEndPoint(), @@ -226,7 +232,7 @@ public void setResultTestName(ITestResult result) { @AfterClass(alwaysRun = true) public void waittime() { if (!testCaseName.contains(GlobalConstants._AUTHENTICATEUSER) - && isOTPEnabled().equals("true")) { + && MimotoUtil.isOTPEnabled().equals("true")) { try { long delayTime = Long.parseLong(properties.getProperty("Delaytime")); if (!BaseTestCase.isTargetEnvLTS()) diff --git a/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/PostWithBodyWithOtpGenerate.java b/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/PostWithBodyWithOtpGenerate.java index 1cded4cf..39d9d51e 100644 --- a/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/PostWithBodyWithOtpGenerate.java +++ b/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/PostWithBodyWithOtpGenerate.java @@ -28,6 +28,7 @@ import io.mosip.testrig.apirig.utils.AuthenticationTestException; import io.mosip.testrig.apirig.utils.ConfigManager; import io.mosip.testrig.apirig.utils.GlobalConstants; +import io.mosip.testrig.apirig.utils.MimotoUtil; import io.mosip.testrig.apirig.utils.OutputValidationUtil; import io.mosip.testrig.apirig.utils.ReportUtil; import io.restassured.response.Response; @@ -91,7 +92,7 @@ public void test(TestCaseDTO testCaseDTO) throws AuthenticationTestException, Ad } } - testCaseName = isTestCaseValidForExecution(testCaseDTO); + testCaseName = MimotoUtil.isTestCaseValidForExecution(testCaseDTO); auditLogCheck = testCaseDTO.isAuditLogCheck(); String tempUrl = ConfigManager.getEsignetBaseUrl(); JSONObject req = new JSONObject(testCaseDTO.getInput()); diff --git a/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/PostWithFormDataBodyForPdfDownload.java b/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/PostWithFormDataBodyForPdfDownload.java index 8897361f..4c0b1d19 100644 --- a/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/PostWithFormDataBodyForPdfDownload.java +++ b/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/PostWithFormDataBodyForPdfDownload.java @@ -30,6 +30,7 @@ import io.mosip.testrig.apirig.utils.ConfigManager; import io.mosip.testrig.apirig.utils.GlobalConstants; import io.mosip.testrig.apirig.utils.GlobalMethods; +import io.mosip.testrig.apirig.utils.MimotoUtil; import io.restassured.response.Response; public class PostWithFormDataBodyForPdfDownload extends AdminTestUtil implements ITest { @@ -80,7 +81,7 @@ public Object[] getTestCaseList(ITestContext context) { @Test(dataProvider = "testcaselist") public void test(TestCaseDTO testCaseDTO) throws AuthenticationTestException, AdminTestException { testCaseName = testCaseDTO.getTestCaseName(); - testCaseName = isTestCaseValidForExecution(testCaseDTO); + testCaseName = MimotoUtil.isTestCaseValidForExecution(testCaseDTO); if (HealthChecker.signalTerminateExecution) { throw new SkipException(GlobalConstants.TARGET_ENV_HEALTH_CHECK_FAILED + HealthChecker.healthCheckFailureMapS); } diff --git a/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/SimplePost.java b/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/SimplePost.java index 70b97512..f5c176df 100644 --- a/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/SimplePost.java +++ b/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/SimplePost.java @@ -30,6 +30,7 @@ import io.mosip.testrig.apirig.utils.AuthenticationTestException; import io.mosip.testrig.apirig.utils.ConfigManager; import io.mosip.testrig.apirig.utils.GlobalConstants; +import io.mosip.testrig.apirig.utils.MimotoUtil; import io.mosip.testrig.apirig.utils.OutputValidationUtil; import io.mosip.testrig.apirig.utils.ReportUtil; import io.restassured.response.Response; @@ -82,7 +83,7 @@ public Object[] getTestCaseList(ITestContext context) { @Test(dataProvider = "testcaselist") public void test(TestCaseDTO testCaseDTO) throws AuthenticationTestException, AdminTestException { testCaseName = testCaseDTO.getTestCaseName(); - testCaseName = isTestCaseValidForExecution(testCaseDTO); + testCaseName = MimotoUtil.isTestCaseValidForExecution(testCaseDTO); auditLogCheck = testCaseDTO.isAuditLogCheck(); String[] templateFields = testCaseDTO.getTemplateFields(); if (HealthChecker.signalTerminateExecution) { diff --git a/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/SimplePostForAutoGenId.java b/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/SimplePostForAutoGenId.java index b984eca2..5489833b 100644 --- a/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/SimplePostForAutoGenId.java +++ b/apitest/src/main/java/io/mosip/testrig/apirig/testscripts/SimplePostForAutoGenId.java @@ -31,6 +31,7 @@ import io.mosip.testrig.apirig.utils.AuthenticationTestException; import io.mosip.testrig.apirig.utils.ConfigManager; import io.mosip.testrig.apirig.utils.GlobalConstants; +import io.mosip.testrig.apirig.utils.MimotoUtil; import io.mosip.testrig.apirig.utils.OutputValidationUtil; import io.mosip.testrig.apirig.utils.ReportUtil; import io.restassured.response.Response; @@ -98,7 +99,7 @@ public void test(TestCaseDTO testCaseDTO) } } - testCaseName = isTestCaseValidForExecution(testCaseDTO); + testCaseName = MimotoUtil.isTestCaseValidForExecution(testCaseDTO); String[] templateFields = testCaseDTO.getTemplateFields(); String inputJson = ""; @@ -153,6 +154,11 @@ public void test(TestCaseDTO testCaseDTO) //tempUrl = ApplnURI.replace(GlobalConstants.API_INTERNAL, ConfigManager.getSunBirdBaseURL()); testCaseDTO.setEndPoint(testCaseDTO.getEndPoint().replace("$SUNBIRDBASEURL$", "")); } + + if (inputJson.contains("$GETCLIENTIDFROMMIMOTOACTUATOR$")) { + inputJson = replaceKeywordWithValue(inputJson, "$GETCLIENTIDFROMMIMOTOACTUATOR$", + getValueFromMimotoActuator("overrides", "mimoto.oidc.partner.clientid")); + } if (testCaseName.contains("_AuthorizationCode_")) { response = postRequestWithCookieAuthHeaderAndXsrfTokenForAutoGenId( tempUrl + testCaseDTO.getEndPoint(), inputJson, COOKIENAME, testCaseDTO.getTestCaseName(), diff --git a/apitest/src/main/java/io/mosip/testrig/apirig/utils/MimotoUtil.java b/apitest/src/main/java/io/mosip/testrig/apirig/utils/MimotoUtil.java new file mode 100644 index 00000000..5327f755 --- /dev/null +++ b/apitest/src/main/java/io/mosip/testrig/apirig/utils/MimotoUtil.java @@ -0,0 +1,83 @@ +package io.mosip.testrig.apirig.utils; + +import org.apache.log4j.Logger; +import org.json.JSONObject; +import org.testng.SkipException; + +import io.mosip.testrig.apirig.dto.TestCaseDTO; +import io.mosip.testrig.apirig.testrunner.BaseTestCase; +import io.mosip.testrig.apirig.testrunner.MockSMTPListener; + +public class MimotoUtil extends AdminTestUtil { + + private static final Logger logger = Logger.getLogger(MimotoUtil.class); + public static final String SEND_OTP_ENDPOINT = "mimoto/req/"; + public static final String MIMOTO_CREDENTIAL_STATUS = "Mimoto_CredentialsStatus_"; + public static final String OTP_FEATURE_NOT_SUPPORTED = "OTP feature not supported. Hence skipping the testcase"; + + + private static String otpEnabled = "false"; + + public static String isOTPEnabled() { + String value = getValueFromMimotoActuator("/mimoto-default.properties", "mosip.otp.download.enable").isBlank() + ? System.getenv("isOTPEnabled") + : getValueFromMimotoActuator("/mimoto-default.properties", "mosip.otp.download.enable"); + if (value != null && !(value.isBlank())) + otpEnabled = value; + return otpEnabled; + } + + public static String isTestCaseValidForExecution(TestCaseDTO testCaseDTO) { + String testCaseName = testCaseDTO.getTestCaseName(); + if (isOTPEnabled().equals("false") && (testCaseDTO.getEndPoint().contains(SEND_OTP_ENDPOINT) + || testCaseDTO.getInput().contains(SEND_OTP_ENDPOINT) + || testCaseName.startsWith(MIMOTO_CREDENTIAL_STATUS) || testCaseName.contains("_vid") + || testCaseName.contains("_VID"))) { + throw new SkipException(OTP_FEATURE_NOT_SUPPORTED); + } + return testCaseName; + } + + public static String getOTPFromSMTP(String inputJson, TestCaseDTO testCaseDTO) { + String testCaseName = testCaseDTO.getTestCaseName(); + JSONObject request = new JSONObject(inputJson); + String emailId = null; + String otp = null; + + + if (testCaseName.contains("ESignet_AuthenticateUser") && request.has(GlobalConstants.REQUEST)) { + if (request.getJSONObject(GlobalConstants.REQUEST).has(GlobalConstants.CHALLENGELIST)) { + if (request.getJSONObject(GlobalConstants.REQUEST).getJSONArray(GlobalConstants.CHALLENGELIST) + .length() > 0) { + if (request.getJSONObject(GlobalConstants.REQUEST).getJSONArray(GlobalConstants.CHALLENGELIST) + .getJSONObject(0).has(GlobalConstants.CHALLENGE)) { + if (request.getJSONObject(GlobalConstants.REQUEST).getJSONArray(GlobalConstants.CHALLENGELIST) + .getJSONObject(0).getString(GlobalConstants.CHALLENGE) + .endsWith(GlobalConstants.MAILINATOR_COM) + || request.getJSONObject(GlobalConstants.REQUEST) + .getJSONArray(GlobalConstants.CHALLENGELIST).getJSONObject(0) + .getString(GlobalConstants.CHALLENGE).endsWith(GlobalConstants.MOSIP_NET) + || request.getJSONObject(GlobalConstants.REQUEST) + .getJSONArray(GlobalConstants.CHALLENGELIST).getJSONObject(0) + .getString(GlobalConstants.CHALLENGE).endsWith(GlobalConstants.OTP_AS_PHONE)) { + emailId = request.getJSONObject(GlobalConstants.REQUEST) + .getJSONArray(GlobalConstants.CHALLENGELIST).getJSONObject(0) + .getString(GlobalConstants.CHALLENGE); + if (emailId.endsWith(GlobalConstants.OTP_AS_PHONE)) + emailId = emailId.replace(GlobalConstants.OTP_AS_PHONE, ""); + logger.info(emailId); + otp = MockSMTPListener.getOtp(emailId); + request.getJSONObject(GlobalConstants.REQUEST).getJSONArray(GlobalConstants.CHALLENGELIST) + .getJSONObject(0).put(GlobalConstants.CHALLENGE, otp); + inputJson = request.toString(); + return inputJson; + } + } + } + } + } + + return inputJson; + } + +} \ No newline at end of file diff --git a/apitest/src/main/resources/config/Kernel.properties b/apitest/src/main/resources/config/Kernel.properties index 34b12aae..b35b0701 100644 --- a/apitest/src/main/resources/config/Kernel.properties +++ b/apitest/src/main/resources/config/Kernel.properties @@ -101,7 +101,7 @@ auditActuatorEndpoint=/v1/auditmanager/actuator/info validateBindingEndpoint=ida-binding esignetWellKnownEndPoint=/v1/esignet/oidc/.well-known/openid-configuration signupSettingsEndPoint=/v1/signup/settings -actuatorMimotoEndpoint=/v1/mimoto/actuator/env +actuatorMimotoEndpoint=/residentmobileapp/actuator/env esignetActuatorPropertySection=esignet-default.properties @@ -137,17 +137,17 @@ AuthClientID = mosip-resident-client #---------------------------------- Client Secret Keys -----------------------# #-- When test rig ran in docker, these values dervied from the environment ---# -mosip_partner_client_secret = vXS7WUyPDpfWYuoz -mosip_pms_client_secret = 5Qj8vn989OL1Vlu6 -mosip_resident_client_secret = SnZQ6nnVwN9YWvdM -mosip_idrepo_client_secret = AeM2TwFuuZygCuvO -mosip_reg_client_secret = DLXygc82rkAkjrwV -mosip_admin_client_secret = Styop9nqkshXMTgj -mosip_hotlist_client_secret = TKyc4cqWymxjiLEsVydX4uME1xU3i9xl -mosip_regproc_client_secret = eyeXdyhO0u2ETibw -mpartner_default_mobile_secret = iCkj8BRZU6hP6MAN -mosip_testrig_client_secret = AonuXbikoWmHP5ug -AuthClientSecret = SnZQ6nnVwN9YWvdM +mosip_partner_client_secret = w6z9XQQ6Toi5vzzY +mosip_pms_client_secret = 3XiMpmPfAAzT47EC +mosip_resident_client_secret = MiTOjWLVoFZw3CHZ +mosip_idrepo_client_secret = qKNTW5CTxKsgVGjw +mosip_reg_client_secret = Msc7sItq6Rg8vcEC +mosip_admin_client_secret = auWjWiniqX0YX8KF +mosip_hotlist_client_secret = lA7pCSLknLvT9Owj +mosip_regproc_client_secret = rR5eKHfG4i3BJf8S +mpartner_default_mobile_secret = duo1HolnpqNc6aMA +mosip_testrig_client_secret = G9qAJ3SrOm575GqL +AuthClientSecret = MiTOjWLVoFZw3CHZ @@ -169,8 +169,8 @@ new_Resident_Password = mosip123 new_Resident_Role = default-roles-mosip,PARTNER_ADMIN roles.111995 = PARTNER_ADMIN,default-roles-mosip keycloak_UserName = admin -keycloak_Password = sMDr9Ainw9 -keycloak-external-url = https://iam.qa-inji.mosip.net +keycloak_Password = DyWRaJqTFh +keycloak-external-url = https://iam.released.mosip.net keycloak-realm-id = mosip iam-users-to-create = 111997,111998,220005,111992,globaladmin,111887,111999 iam-users-password = mosip123,mosip123,mosip123,mosip123,mosip123 @@ -190,15 +190,15 @@ pool_size=1 dialect=org.hibernate.dialect.PostgreSQLDialect show_sql=true current_session_context_class=thread -audit_url=jdbc:postgresql://qa-inji.mosip.net:5432/mosip_audit +audit_url=jdbc:postgresql://released.mosip.net:5432/mosip_audit audit_username=postgres -audit_password=2BhgiSpCaT +audit_password=WfJpMctLjp audit_default_schema=audit DB_PORT= installation-domain= -partner_url=jdbc:postgresql://qa-inji.mosip.net:5432/mosip_ida +partner_url=jdbc:postgresql://released.mosip.net:5432/mosip_ida partner_username=postgres -partner_password=2BhgiSpCaT +partner_password=WfJpMctLjp partner_default_schema=partner reportLogPath=automationLogAndReport postgresqlUser=postgresql @@ -210,7 +210,7 @@ hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect hibernate.show_sql=true hibernate.current_session_context_class=thread db-su-user=postgres -postgres-password=2BhgiSpCaT +postgres-password=WfJpMctLjp pms_db_schema=pms km_db_schema=keymgr master_db_schema=master @@ -261,7 +261,7 @@ admin_password=mosip123 admin_userName=220005 admin_zone_password=mosip123 admin_zone_userName=globaladmin - +mockNotificationChannel=email,phone #------------------------- Need to check if these are used or not ------------------------# diff --git a/apitest/src/main/resources/mimoto/SunBirdR/GetPolicySunBirdR/GetPolicySunBirdR.yml b/apitest/src/main/resources/mimoto/SunBirdR/GetPolicySunBirdR/GetPolicySunBirdR.yml index d8eef669..bdd605de 100644 --- a/apitest/src/main/resources/mimoto/SunBirdR/GetPolicySunBirdR/GetPolicySunBirdR.yml +++ b/apitest/src/main/resources/mimoto/SunBirdR/GetPolicySunBirdR/GetPolicySunBirdR.yml @@ -1,5 +1,5 @@ GetPolicySunBirdR: - Mimoto_ESignet_SunBirdR_DeletePolicy_NOAUTH_Valid_Smoke: + Mimoto_ESignet_SunBirdR_GetPolicy_NOAUTH_Valid_Smoke: endPoint: $SUNBIRDBASEURL$/api/v1/Insurance/{insuranceid} role: resident restMethod: get diff --git a/apitest/testNgXmlFiles/mimotoApi.xml b/apitest/testNgXmlFiles/mimotoApi.xml index 3237e5a1..8add7cfd 100644 --- a/apitest/testNgXmlFiles/mimotoApi.xml +++ b/apitest/testNgXmlFiles/mimotoApi.xml @@ -1,7 +1,7 @@ - + @@ -32,75 +32,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -173,28 +104,5 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/helm/inji-config-server/values.yaml b/helm/inji-config-server/values.yaml index 8b71e907..3ee9b481 100755 --- a/helm/inji-config-server/values.yaml +++ b/helm/inji-config-server/values.yaml @@ -103,6 +103,18 @@ envVariables: - name: SPRING_CLOUD_CONFIG_SERVER_OVERRIDES_MOSIP_ESIGNET_INSURANCE_HOST valueFrom: configMapKeyRef: - key: mosip-esignet-insurance-host - name: global + key: mosip-esignet-insurance-host + name: global enabled: true + + - name: SPRING_CLOUD_CONFIG_SERVER_OVERRIDES_MOSIP_INJI_DATASHARE_HOST + valueFrom: + configMapKeyRef: + key: mosip-inji-datashare-host + name: global + + - name: SPRING_CLOUD_CONFIG_SERVER_OVERRIDES_MOSIP_INJIWEB_HOST + valueFrom: + configMapKeyRef: + key: mosip-injiweb-host + name: global diff --git a/pom.xml b/pom.xml index 5a23fb16..62c29858 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.mosip mimoto - 0.13.0-java21-SNAPSHOT + 0.14.0-SNAPSHOT mimoto https://github.com/mosip/mimoto Mobile server backend supporting Inji. diff --git a/src/main/java/io/mosip/mimoto/dto/BackgroundImageDTO.java b/src/main/java/io/mosip/mimoto/dto/BackgroundImageDTO.java index 7c8ad6b1..22f306bd 100644 --- a/src/main/java/io/mosip/mimoto/dto/BackgroundImageDTO.java +++ b/src/main/java/io/mosip/mimoto/dto/BackgroundImageDTO.java @@ -1,14 +1,18 @@ package io.mosip.mimoto.dto; import com.google.gson.annotations.Expose; +import jakarta.validation.constraints.NotBlank; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.URL; @Data @AllArgsConstructor @NoArgsConstructor public class BackgroundImageDTO { @Expose + @URL + @NotBlank String uri; } diff --git a/src/main/java/io/mosip/mimoto/dto/IssuerDTO.java b/src/main/java/io/mosip/mimoto/dto/IssuerDTO.java index 992a72af..1e0a7c71 100644 --- a/src/main/java/io/mosip/mimoto/dto/IssuerDTO.java +++ b/src/main/java/io/mosip/mimoto/dto/IssuerDTO.java @@ -30,6 +30,7 @@ public class IssuerDTO { @Expose @NotBlank String client_id; + @NotBlank @SerializedName(".well-known") @JsonProperty(".well-known") @Expose diff --git a/src/main/java/io/mosip/mimoto/dto/LogoDTO.java b/src/main/java/io/mosip/mimoto/dto/LogoDTO.java index 89697d79..cce525a7 100644 --- a/src/main/java/io/mosip/mimoto/dto/LogoDTO.java +++ b/src/main/java/io/mosip/mimoto/dto/LogoDTO.java @@ -5,11 +5,13 @@ import lombok.Data; import jakarta.validation.constraints.NotBlank; +import org.hibernate.validator.constraints.URL; @Data public class LogoDTO { @Expose @NotBlank + @URL String url; @Expose @NotBlank diff --git a/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialDefinitionResponseDto.java b/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialDefinitionResponseDto.java index d71c3419..ac1bc541 100644 --- a/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialDefinitionResponseDto.java +++ b/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialDefinitionResponseDto.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.google.gson.annotations.SerializedName; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; import lombok.Data; import java.util.List; @@ -9,11 +11,15 @@ @Data public class CredentialDefinitionResponseDto { + + @NotEmpty @SerializedName("type") @JsonProperty("type") - private List type; + private List<@NotEmpty String> type; + @NotEmpty + @Valid @SerializedName("credentialSubject") @JsonProperty("credentialSubject") - private Map credentialSubject; + private Map<@NotEmpty String, @Valid CredentialDisplayResponseDto> credentialSubject; } diff --git a/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialDisplayResponseDto.java b/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialDisplayResponseDto.java index 8f5ff40f..eeec2af8 100644 --- a/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialDisplayResponseDto.java +++ b/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialDisplayResponseDto.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.google.gson.annotations.SerializedName; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; import lombok.Data; import java.util.List; @@ -9,7 +11,9 @@ @Data public class CredentialDisplayResponseDto { + @NotEmpty + @Valid @SerializedName("display") @JsonProperty("display") - private List display; + private List<@Valid CredentialIssuerDisplayResponse> display; } diff --git a/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialIssuerDisplayResponse.java b/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialIssuerDisplayResponse.java index 801e5ac7..0fd6694d 100644 --- a/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialIssuerDisplayResponse.java +++ b/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialIssuerDisplayResponse.java @@ -2,15 +2,18 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.google.gson.annotations.SerializedName; +import jakarta.validation.constraints.NotBlank; import lombok.Data; @Data public class CredentialIssuerDisplayResponse { + @NotBlank @SerializedName("name") @JsonProperty("name") private String name; + @NotBlank @SerializedName("locale") @JsonProperty("locale") private String locale; diff --git a/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialIssuerWellKnownResponse.java b/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialIssuerWellKnownResponse.java index 70d5bfc7..17cb26ea 100644 --- a/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialIssuerWellKnownResponse.java +++ b/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialIssuerWellKnownResponse.java @@ -2,26 +2,38 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.google.gson.annotations.SerializedName; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.Pattern; import lombok.Data; +import org.hibernate.validator.constraints.URL; import java.util.List; import java.util.Map; @Data public class CredentialIssuerWellKnownResponse { + @NotBlank + @URL @SerializedName("credential_issuer") @JsonProperty("credential_issuer") private String credentialIssuer; + @NotEmpty @SerializedName("authorization_servers") @JsonProperty("authorization_servers") - private List authorizationServers; + private List<@NotBlank @URL String> authorizationServers; + @NotBlank @SerializedName("credential_endpoint") + @Pattern(regexp = "https?://.*?/credential$") @JsonProperty("credential_endpoint") private String credentialEndPoint; + @NotEmpty + @Valid @SerializedName("credential_configurations_supported") @JsonProperty("credential_configurations_supported") - private Map credentialConfigurationsSupported; + private Map<@NotBlank String, @Valid CredentialsSupportedResponse> credentialConfigurationsSupported; } diff --git a/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialSupportedDisplayResponse.java b/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialSupportedDisplayResponse.java index 0dd986b6..53d2ea5e 100644 --- a/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialSupportedDisplayResponse.java +++ b/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialSupportedDisplayResponse.java @@ -5,6 +5,7 @@ import com.google.gson.annotations.SerializedName; import io.mosip.mimoto.dto.BackgroundImageDTO; import io.mosip.mimoto.dto.LogoDTO; +import jakarta.validation.constraints.NotNull; import lombok.Data; import jakarta.validation.Valid; @@ -23,13 +24,15 @@ public class CredentialSupportedDisplayResponse { String locale; @Expose + @NotNull @Valid LogoDTO logo; @JsonProperty("background_image") @SerializedName("background_image") @Expose - @NotBlank + @Valid + @NotNull BackgroundImageDTO backgroundImage; @JsonProperty("background_color") diff --git a/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialsSupportedResponse.java b/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialsSupportedResponse.java index 0e6b0918..4c87de3d 100644 --- a/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialsSupportedResponse.java +++ b/src/main/java/io/mosip/mimoto/dto/mimoto/CredentialsSupportedResponse.java @@ -2,27 +2,41 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.google.gson.annotations.SerializedName; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import lombok.Data; import java.util.List; import java.util.Map; -import java.util.Set; @Data public class CredentialsSupportedResponse { + + @NotBlank(message = "Format must not be blank") private String format; + + @NotBlank(message = "Scope must not be blank") private String scope; + @NotEmpty(message = "Proof types supported must not be empty") + @Valid @SerializedName("proof_types_supported") @JsonProperty("proof_types_supported") - private Map proofTypesSupported; + private Map<@NotEmpty String, @Valid ProofTypesSupported> proofTypesSupported; + @Valid + @NotNull @SerializedName("credential_definition") @JsonProperty("credential_definition") private CredentialDefinitionResponseDto credentialDefinition; + @NotEmpty(message = "Display information must not be empty") + @Valid @SerializedName("display") @JsonProperty("display") - private List display; + private List<@Valid CredentialSupportedDisplayResponse> display; + private List order; } diff --git a/src/main/java/io/mosip/mimoto/dto/mimoto/ProofTypesSupported.java b/src/main/java/io/mosip/mimoto/dto/mimoto/ProofTypesSupported.java index 303b7497..15cfe4b4 100644 --- a/src/main/java/io/mosip/mimoto/dto/mimoto/ProofTypesSupported.java +++ b/src/main/java/io/mosip/mimoto/dto/mimoto/ProofTypesSupported.java @@ -2,10 +2,15 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.google.gson.annotations.SerializedName; +import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotEmpty; import java.util.List; public class ProofTypesSupported { + + @NotEmpty + @NotNull @JsonProperty("proof_signing_alg_values_supported") @SerializedName("proof_signing_alg_values_supported") private List proofSigningAlgValuesSupported; diff --git a/src/main/java/io/mosip/mimoto/exception/InvalidWellknownResponseException.java b/src/main/java/io/mosip/mimoto/exception/InvalidWellknownResponseException.java new file mode 100644 index 00000000..4e466e7e --- /dev/null +++ b/src/main/java/io/mosip/mimoto/exception/InvalidWellknownResponseException.java @@ -0,0 +1,21 @@ +package io.mosip.mimoto.exception; + +public class InvalidWellknownResponseException extends BaseCheckedException { + + public InvalidWellknownResponseException() { + super(PlatformErrorMessages.INVALID_CREDENTIAL_ISSUER_WELLKNOWN_RESPONSE_EXCEPTION.getCode(),PlatformErrorMessages.INVALID_CREDENTIAL_ISSUER_WELLKNOWN_RESPONSE_EXCEPTION.getMessage()); + } + + public InvalidWellknownResponseException(String message) { + super(PlatformErrorMessages.INVALID_CREDENTIAL_ISSUER_WELLKNOWN_RESPONSE_EXCEPTION.getCode(),PlatformErrorMessages.INVALID_CREDENTIAL_ISSUER_WELLKNOWN_RESPONSE_EXCEPTION.getMessage()+"\n"+message); + + } + + public InvalidWellknownResponseException(String message, Throwable cause) { + super(PlatformErrorMessages.INVALID_CREDENTIAL_ISSUER_WELLKNOWN_RESPONSE_EXCEPTION.getCode(),message, cause); + } + + protected InvalidWellknownResponseException( Throwable cause) { + super(PlatformErrorMessages.INVALID_CREDENTIAL_ISSUER_WELLKNOWN_RESPONSE_EXCEPTION.getCode(),PlatformErrorMessages.INVALID_CREDENTIAL_ISSUER_WELLKNOWN_RESPONSE_EXCEPTION.getMessage(),cause); + } +} diff --git a/src/main/java/io/mosip/mimoto/exception/PlatformErrorMessages.java b/src/main/java/io/mosip/mimoto/exception/PlatformErrorMessages.java index 38f2d837..cfaaa813 100644 --- a/src/main/java/io/mosip/mimoto/exception/PlatformErrorMessages.java +++ b/src/main/java/io/mosip/mimoto/exception/PlatformErrorMessages.java @@ -86,7 +86,8 @@ public enum PlatformErrorMessages { MIMOTO_ISSUER_ONBOARDING_EXCEPTION(PlatformConstants.PREFIX + "037", "Issuers Onboarding exception occurred "), INVALID_VERIFIER_ID_EXCEPTION(PlatformConstants.PREFIX + "038", "Invalid Verifier ClientId"), INVALID_VERIFIER_REDIRECT_URI_EXCEPTION(PlatformConstants.PREFIX + "039", "Invalid Redirect Uri"), - INVALID_CREDENTIAL_RESOURCE_URI_EXCEPTION(PlatformConstants.PREFIX + "040", "The Credential Resource is Invalid"); + INVALID_CREDENTIAL_RESOURCE_URI_EXCEPTION(PlatformConstants.PREFIX + "040", "The Credential Resource is Invalid"), + INVALID_CREDENTIAL_ISSUER_WELLKNOWN_RESPONSE_EXCEPTION(PlatformConstants.PREFIX + "041", "Invalid Wellknown from Issuer"); /** The error message. */ private final String errorMessage; diff --git a/src/main/java/io/mosip/mimoto/service/impl/IssuersServiceImpl.java b/src/main/java/io/mosip/mimoto/service/impl/IssuersServiceImpl.java index 0d98bb7f..f23329df 100644 --- a/src/main/java/io/mosip/mimoto/service/impl/IssuersServiceImpl.java +++ b/src/main/java/io/mosip/mimoto/service/impl/IssuersServiceImpl.java @@ -12,10 +12,14 @@ import io.mosip.mimoto.dto.mimoto.CredentialsSupportedResponse; import io.mosip.mimoto.exception.ApiNotAccessibleException; import io.mosip.mimoto.exception.InvalidIssuerIdException; +import io.mosip.mimoto.exception.InvalidWellknownResponseException; import io.mosip.mimoto.service.IssuersService; +import io.mosip.mimoto.util.CredentialIssuerWellknownResponseValidator; import io.mosip.mimoto.util.LoggerUtil; import io.mosip.mimoto.util.RestApiClient; import io.mosip.mimoto.util.Utilities; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validator; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -23,6 +27,7 @@ import java.io.IOException; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @@ -34,6 +39,9 @@ public class IssuersServiceImpl implements IssuersService { @Autowired private Utilities utilities; + @Autowired + private Validator validator; + @Autowired private RestApiClient restApiClient; @@ -107,8 +115,10 @@ public CredentialIssuerWellKnownResponse getIssuerWellknown(String issuerId) thr .map(issuerDTO -> { String wellknownResponse = restApiClient.getApi(issuerDTO.getWellKnownEndpoint(), String.class); try { - return objectMapper.readValue(wellknownResponse,CredentialIssuerWellKnownResponse.class); - } catch (JsonProcessingException e) { + CredentialIssuerWellKnownResponse credentialIssuerWellKnownResponse = objectMapper.readValue(wellknownResponse, CredentialIssuerWellKnownResponse.class); + new CredentialIssuerWellknownResponseValidator().validate(credentialIssuerWellKnownResponse, validator); + return credentialIssuerWellKnownResponse; + } catch (JsonProcessingException | ApiNotAccessibleException | InvalidWellknownResponseException e) { throw new RuntimeException(e); } }) @@ -124,6 +134,8 @@ public CredentialsSupportedResponse getIssuerWellknownForCredentialType(String i } return credentialsSupportedResponse; } + + } diff --git a/src/main/java/io/mosip/mimoto/util/CredentialIssuerWellknownResponseValidator.java b/src/main/java/io/mosip/mimoto/util/CredentialIssuerWellknownResponseValidator.java new file mode 100644 index 00000000..db7cdfc2 --- /dev/null +++ b/src/main/java/io/mosip/mimoto/util/CredentialIssuerWellknownResponseValidator.java @@ -0,0 +1,21 @@ +package io.mosip.mimoto.util; + +import io.mosip.mimoto.dto.mimoto.CredentialIssuerWellKnownResponse; +import io.mosip.mimoto.exception.ApiNotAccessibleException; +import io.mosip.mimoto.exception.InvalidWellknownResponseException; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validator; + +import java.util.Set; +public class CredentialIssuerWellknownResponseValidator { + public void validate(CredentialIssuerWellKnownResponse response, Validator validator) throws ApiNotAccessibleException, InvalidWellknownResponseException { + Set> violations = validator.validate(response); + if (!violations.isEmpty()) { + StringBuilder sb = new StringBuilder("Validation failed:"); + for (ConstraintViolation violation : violations) { + sb.append("\n").append(violation.getPropertyPath()).append(": ").append(violation.getMessage()); + } + throw new InvalidWellknownResponseException(sb.toString()); + } + } +} diff --git a/src/test/java/io/mosip/mimoto/service/IssuersServiceTest.java b/src/test/java/io/mosip/mimoto/service/IssuersServiceTest.java index 72027c05..dd71cb4e 100644 --- a/src/test/java/io/mosip/mimoto/service/IssuersServiceTest.java +++ b/src/test/java/io/mosip/mimoto/service/IssuersServiceTest.java @@ -11,6 +11,7 @@ import io.mosip.mimoto.service.impl.IssuersServiceImpl; import io.mosip.mimoto.util.RestApiClient; import io.mosip.mimoto.util.Utilities; +import jakarta.validation.Validator; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -18,7 +19,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; -import org.springframework.beans.factory.annotation.Autowired; import java.io.IOException; import java.util.ArrayList; @@ -28,6 +28,7 @@ import static io.mosip.mimoto.util.TestUtilities.*; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -37,6 +38,9 @@ public class IssuersServiceTest { @InjectMocks IssuersServiceImpl issuersService = new IssuersServiceImpl(); + @Mock + Validator validator; + @InjectMocks CredentialServiceImpl credentialService = new CredentialServiceImpl(); @@ -101,6 +105,7 @@ public void shouldReturnIssuerWellknownForTheIssuerIdIfExist() throws ApiNotAcce Mockito.when(restApiClient.getApi(wellKnownUrl , String.class)) .thenReturn(getExpectedWellKnownJson()); Mockito.when(objectMapper.readValue(getExpectedWellKnownJson(), CredentialIssuerWellKnownResponse.class)).thenReturn(expextedCredentialIssuerWellKnownResponse); + Mockito.when(validator.validate(any())).thenReturn(Collections.emptySet()); CredentialIssuerWellKnownResponse credentialIssuerWellKnownResponse=issuersService.getIssuerWellknown(issuerId); assertEquals(expextedCredentialIssuerWellKnownResponse,credentialIssuerWellKnownResponse); diff --git a/src/test/java/io/mosip/mimoto/util/CredentialIssuerWellknownResponseValidatorTest.java b/src/test/java/io/mosip/mimoto/util/CredentialIssuerWellknownResponseValidatorTest.java new file mode 100644 index 00000000..b96fd1e3 --- /dev/null +++ b/src/test/java/io/mosip/mimoto/util/CredentialIssuerWellknownResponseValidatorTest.java @@ -0,0 +1,233 @@ +package io.mosip.mimoto.util; + +import io.mosip.mimoto.dto.BackgroundImageDTO; +import io.mosip.mimoto.dto.mimoto.CredentialDefinitionResponseDto; +import io.mosip.mimoto.dto.mimoto.CredentialIssuerWellKnownResponse; +import io.mosip.mimoto.dto.mimoto.CredentialSupportedDisplayResponse; +import io.mosip.mimoto.dto.mimoto.CredentialsSupportedResponse; +import io.mosip.mimoto.exception.ApiNotAccessibleException; +import io.mosip.mimoto.exception.InvalidWellknownResponseException; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static io.mosip.mimoto.util.TestUtilities.getCredentialIssuerWellKnownResponseDto; +import static io.mosip.mimoto.util.TestUtilities.getCredentialSupportedResponse; +import static org.junit.Assert.assertThrows; + +public class CredentialIssuerWellknownResponseValidatorTest { + + @Autowired + private Validator validator; + + @BeforeEach + void setUp() { + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + validator = factory.getValidator(); + } + + @Test + public void shouldThrowExceptionWhenCredentialIssuerIsMissingInCredentialIssuerWellknownResponse() throws ApiNotAccessibleException { + CredentialIssuerWellKnownResponse response = getCredentialIssuerWellKnownResponseDto("Issuer1", + Map.of("CredentialType1", getCredentialSupportedResponse("CredentialType1"))); + + response.setCredentialIssuer(""); + response.setCredentialEndPoint("http://example.com"); + + CredentialIssuerWellknownResponseValidator credentialIssuerWellknownResponseValidator = new CredentialIssuerWellknownResponseValidator(); + InvalidWellknownResponseException invalidWellknownResponseException = assertThrows(InvalidWellknownResponseException.class, () -> + credentialIssuerWellknownResponseValidator.validate(response, validator)); + Assertions.assertEquals("RESIDENT-APP-041", invalidWellknownResponseException.getErrorCode()); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("credentialIssuer: must not be blank"), "Exception message should indicate the missing 'credentialIssuer'"); + } + + @Test + public void shouldThrowExceptionWhenCredentialEndpointIsIncorrectInCredentialIssuerWellknownResponse() throws ApiNotAccessibleException { + CredentialIssuerWellKnownResponse response = getCredentialIssuerWellKnownResponseDto("Issuer1", + Map.of("CredentialType1", getCredentialSupportedResponse("CredentialType1"))); + + response.setCredentialEndPoint("http://example.com"); // Incorrect because it does not end with "/credential" + + CredentialIssuerWellknownResponseValidator credentialIssuerWellknownResponseValidator = new CredentialIssuerWellknownResponseValidator(); + InvalidWellknownResponseException invalidWellknownResponseException = assertThrows(InvalidWellknownResponseException.class, () -> + credentialIssuerWellknownResponseValidator.validate(response, validator)); + Assertions.assertEquals("RESIDENT-APP-041", invalidWellknownResponseException.getErrorCode()); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("credentialEndPoint: must match \"https?://.*?/credential$\""), "Exception message should indicate the incorrect 'credentialEndpoint'"); + } + + @Test + public void shouldThrowExceptionWhenAuthorizationServersIsEmpty() { + CredentialIssuerWellKnownResponse response = getCredentialIssuerWellKnownResponseDto("Issuer1", + Map.of("CredentialType1", getCredentialSupportedResponse("CredentialType1"))); + + response.setCredentialIssuer("https://valid.url/credential"); + response.setAuthorizationServers(Collections.emptyList()); // Invalid empty list + + CredentialIssuerWellknownResponseValidator credentialIssuerWellknownResponseValidator = new CredentialIssuerWellknownResponseValidator(); + InvalidWellknownResponseException invalidWellknownResponseException = assertThrows(InvalidWellknownResponseException.class, () -> + credentialIssuerWellknownResponseValidator.validate(response, validator)); + Assertions.assertEquals("RESIDENT-APP-041", invalidWellknownResponseException.getErrorCode()); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("authorizationServers: must not be empty"), "Exception message should indicate 'authorizationServers' cannot be empty"); + } + + @Test + public void shouldThrowExceptionWhenFormatIsMissingInCredentialsSupported() { + CredentialIssuerWellKnownResponse response = getCredentialIssuerWellKnownResponseDto("Issuer1", + Map.of("CredentialType1", new CredentialsSupportedResponse())); // `format` is not set, default is null + + response.getCredentialConfigurationsSupported().get("CredentialType1").setFormat(null); + + CredentialIssuerWellknownResponseValidator credentialIssuerWellknownResponseValidator = new CredentialIssuerWellknownResponseValidator(); + InvalidWellknownResponseException invalidWellknownResponseException = assertThrows(InvalidWellknownResponseException.class, () -> + credentialIssuerWellknownResponseValidator.validate(response, validator)); + Assertions.assertEquals("RESIDENT-APP-041", invalidWellknownResponseException.getErrorCode()); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("format: Format must not be blank"), "Exception message should indicate 'format' must not be blank"); + } + + @Test + public void shouldThrowExceptionWhenCredentialDefinitionTypeIsEmpty() { + CredentialIssuerWellKnownResponse response = getCredentialIssuerWellKnownResponseDto("Issuer1", + Map.of("CredentialType1", getCredentialSupportedResponse("CredentialType1"))); + response.getCredentialConfigurationsSupported().get("CredentialType1").getCredentialDefinition().setType(Collections.emptyList()); // Invalid empty list + + CredentialIssuerWellknownResponseValidator credentialIssuerWellknownResponseValidator = new CredentialIssuerWellknownResponseValidator(); + InvalidWellknownResponseException invalidWellknownResponseException = assertThrows(InvalidWellknownResponseException.class, () -> + credentialIssuerWellknownResponseValidator.validate(response, validator)); + Assertions.assertEquals("RESIDENT-APP-041", invalidWellknownResponseException.getErrorCode()); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("type: must not be empty"), "Exception message should indicate 'type' must not be empty"); + } + + @Test + public void shouldThrowExceptionWhenLogoUrlIsInvalid() { + CredentialIssuerWellKnownResponse response = getCredentialIssuerWellKnownResponseDto("Issuer1", + Map.of("CredentialType1", getCredentialSupportedResponse("CredentialType1"))); + response.getCredentialConfigurationsSupported().get("CredentialType1").getDisplay().getFirst().getLogo().setUrl("ftp//invalid-url"); // Invalid URL + CredentialIssuerWellknownResponseValidator credentialIssuerWellknownResponseValidator = new CredentialIssuerWellknownResponseValidator(); + InvalidWellknownResponseException invalidWellknownResponseException = assertThrows(InvalidWellknownResponseException.class, () -> + credentialIssuerWellknownResponseValidator.validate(response, validator)); + Assertions.assertEquals("RESIDENT-APP-041", invalidWellknownResponseException.getErrorCode()); + System.out.println(invalidWellknownResponseException.getMessage()); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("logo.url: must be a valid URL"), "Exception message should indicate 'logo.url' must be a valid URL"); + } + + @Test + public void shouldThrowExceptionWhenBackgroundImageUrlIsInvalid() { + CredentialIssuerWellKnownResponse response = getCredentialIssuerWellKnownResponseDto("Issuer1", + Map.of("CredentialType1", getCredentialSupportedResponse("CredentialType1"))); + + response.getCredentialConfigurationsSupported().get("CredentialType1").getDisplay().getFirst().setBackgroundImage(new BackgroundImageDTO("local//imgbasebase64")); + + CredentialIssuerWellknownResponseValidator credentialIssuerWellknownResponseValidator = new CredentialIssuerWellknownResponseValidator(); + InvalidWellknownResponseException invalidWellknownResponseException = assertThrows(InvalidWellknownResponseException.class, () -> + credentialIssuerWellknownResponseValidator.validate(response, validator)); + System.out.println(invalidWellknownResponseException.getMessage()); + Assertions.assertEquals("RESIDENT-APP-041", invalidWellknownResponseException.getErrorCode()); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("backgroundImage.uri: must be a valid URL"), "Exception message should indicate 'background_image.uri' must be a valid URL"); + } + + @Test + public void shouldDetectMissingMandatoryFields() { + + CredentialIssuerWellKnownResponse response = getCredentialIssuerWellKnownResponseDto("Issuer1", + Map.of("CredentialType1", getCredentialSupportedResponse("CredentialType1"))); + response.setCredentialEndPoint(null); + response.setCredentialConfigurationsSupported(null); + response.setAuthorizationServers(null); + response.setCredentialIssuer(null); + CredentialIssuerWellknownResponseValidator credentialIssuerWellknownResponseValidator = new CredentialIssuerWellknownResponseValidator(); + InvalidWellknownResponseException invalidWellknownResponseException = assertThrows(InvalidWellknownResponseException.class, () -> + credentialIssuerWellknownResponseValidator.validate(response, validator)); + Assertions.assertEquals("RESIDENT-APP-041", invalidWellknownResponseException.getErrorCode()); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("authorizationServers: must not be empty")); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("credentialIssuer: must not be blank")); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("credentialConfigurationsSupported: must not be empty")); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("credentialEndPoint: must not be blank")); + + } + + @Test + public void shouldDetectMissingMandatoryFieldsOfCredentialSupportedResponse() { + + CredentialIssuerWellKnownResponse response = getCredentialIssuerWellKnownResponseDto("Issuer1", + Map.of("CredentialType1", getCredentialSupportedResponse("CredentialType1"))); + response.getCredentialConfigurationsSupported().get("CredentialType1").setFormat(null); + response.getCredentialConfigurationsSupported().get("CredentialType1").setScope(null); + response.getCredentialConfigurationsSupported().get("CredentialType1").setDisplay(null); + response.getCredentialConfigurationsSupported().get("CredentialType1").setProofTypesSupported(null); + response.getCredentialConfigurationsSupported().get("CredentialType1").setCredentialDefinition(null); + CredentialIssuerWellknownResponseValidator credentialIssuerWellknownResponseValidator = new CredentialIssuerWellknownResponseValidator(); + InvalidWellknownResponseException invalidWellknownResponseException = assertThrows(InvalidWellknownResponseException.class, () -> + credentialIssuerWellknownResponseValidator.validate(response, validator)); + Assertions.assertEquals("RESIDENT-APP-041", invalidWellknownResponseException.getErrorCode()); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("format: Format must not be blank")); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("scope: Scope must not be blank")); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("proofTypesSupported: Proof types supported must not be empty")); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("credentialDefinition: must not be null")); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("display: Display information must not be empty")); + + } + + @Test + public void shouldDetectMissingProofAlgorithmsSupported() { + CredentialIssuerWellKnownResponse response = getCredentialIssuerWellKnownResponseDto("Issuer1", + Map.of("CredentialType1", getCredentialSupportedResponse("CredentialType1"))); + response.getCredentialConfigurationsSupported().get("CredentialType1").getProofTypesSupported().get("jwt"); + CredentialIssuerWellknownResponseValidator credentialIssuerWellknownResponseValidator = new CredentialIssuerWellknownResponseValidator(); + InvalidWellknownResponseException invalidWellknownResponseException = assertThrows(InvalidWellknownResponseException.class, () -> + credentialIssuerWellknownResponseValidator.validate(response, validator)); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("proofSigningAlgValuesSupported: must not be null")); + } + + @Test + public void shouldDetectMissingMandatoryFieldsOfCredentialSupportedDisplayResponse() { + // Create a new response object with nested display response details + CredentialIssuerWellKnownResponse response = getCredentialIssuerWellKnownResponseDto("Issuer1", + Map.of("CredentialType1", getCredentialSupportedResponse("CredentialType1"))); + List credentialSupportedDisplayResponseList = new ArrayList<>(); + CredentialSupportedDisplayResponse credentialSupportedDisplayResponse = new CredentialSupportedDisplayResponse(); + credentialSupportedDisplayResponse.setLogo(null); + credentialSupportedDisplayResponse.setName(null); + credentialSupportedDisplayResponse.setLocale(null); + credentialSupportedDisplayResponse.setTextColor(null); + credentialSupportedDisplayResponse.setBackgroundColor(null); + credentialSupportedDisplayResponse.setBackgroundImage(null); + credentialSupportedDisplayResponseList.add(credentialSupportedDisplayResponse); + response.getCredentialConfigurationsSupported().get("CredentialType1").setDisplay(credentialSupportedDisplayResponseList); + + CredentialIssuerWellknownResponseValidator credentialIssuerWellknownResponseValidator = new CredentialIssuerWellknownResponseValidator(); + InvalidWellknownResponseException invalidWellknownResponseException = assertThrows(InvalidWellknownResponseException.class, () -> + credentialIssuerWellknownResponseValidator.validate(response, validator) + ); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("name: must not be blank")); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("locale: must not be blank")); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("backgroundImage: must not be null")); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("backgroundColor: must not be blank")); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("textColor: must not be blank")); + } + + @Test + public void shouldDetectMissingMandatoryFieldsOfCredentialDefinitionResponseDtoResponse() { + CredentialIssuerWellKnownResponse response = getCredentialIssuerWellKnownResponseDto("Issuer1", + Map.of("CredentialType1", getCredentialSupportedResponse("CredentialType1"))); + CredentialDefinitionResponseDto credentialDefinitionResponseDto=new CredentialDefinitionResponseDto(); + credentialDefinitionResponseDto.setCredentialSubject(null); + credentialDefinitionResponseDto.setType(null); + response.getCredentialConfigurationsSupported().get("CredentialType1").setCredentialDefinition(credentialDefinitionResponseDto); + + CredentialIssuerWellknownResponseValidator credentialIssuerWellknownResponseValidator = new CredentialIssuerWellknownResponseValidator(); + InvalidWellknownResponseException invalidWellknownResponseException = assertThrows(InvalidWellknownResponseException.class, () -> + credentialIssuerWellknownResponseValidator.validate(response, validator) + ); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("type: must not be empty")); + Assertions.assertTrue(invalidWellknownResponseException.getMessage().contains("credentialSubject: must not be empty")); + } +} diff --git a/src/test/java/io/mosip/mimoto/util/TestUtilities.java b/src/test/java/io/mosip/mimoto/util/TestUtilities.java index 99189342..163a7cad 100644 --- a/src/test/java/io/mosip/mimoto/util/TestUtilities.java +++ b/src/test/java/io/mosip/mimoto/util/TestUtilities.java @@ -40,7 +40,9 @@ public static CredentialsSupportedResponse getCredentialSupportedResponse(String credentialsSupportedResponse.setFormat("ldp_vc"); credentialsSupportedResponse.setScope(credentialSupportedName+"_vc_ldp"); credentialsSupportedResponse.setDisplay(Collections.singletonList(credentialSupportedDisplay)); - credentialsSupportedResponse.setProofTypesSupported(new HashMap<>()); + HashMap proofTypesSupportedHashMap=new HashMap<>(); + proofTypesSupportedHashMap.put("jwt",new ProofTypesSupported()); + credentialsSupportedResponse.setProofTypesSupported(proofTypesSupportedHashMap); credentialsSupportedResponse.setCredentialDefinition(credentialDefinitionResponseDto); return credentialsSupportedResponse; }