diff --git a/ui-test/src/main/java/base/BaseTest.java b/ui-test/src/main/java/base/BaseTest.java index 551e063e6..d7d7ca89a 100644 --- a/ui-test/src/main/java/base/BaseTest.java +++ b/ui-test/src/main/java/base/BaseTest.java @@ -12,7 +12,11 @@ import java.time.Duration; import java.util.Base64; import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import org.json.JSONObject; import org.openqa.selenium.JavascriptExecutor; @@ -79,6 +83,37 @@ public static void beforeAll() { } } + private static final Map CLIENT_CONFIG_MAP = new HashMap<>(); + + static { + CLIENT_CONFIG_MAP.put("@PurposeLogin", + new String[] { "$ID:CreateOIDCClient_with_purpose_type_login_Smoke_sid_clientId$", + "$CLIENT_ASSERTION_PAR_JWT_PURPOSE_LOGIN$" }); + + CLIENT_CONFIG_MAP.put("@PurposeLink", + new String[] { "$ID:CreateOIDCClient_with_purpose_type_link_Smoke_sid_clientId$", + "$CLIENT_ASSERTION_PAR_JWT_PURPOSE_LINK$" }); + + CLIENT_CONFIG_MAP.put("@PurposeNone", + new String[] { "$ID:CreateOIDCClient_with_purpose_type_none_Smoke_sid_clientId$", + "$CLIENT_ASSERTION_PAR_JWT_PURPOSE_NONE$" }); + + CLIENT_CONFIG_MAP.put("@NoPurpose", new String[] { "$ID:CreateOIDCClient_with_no_purpose_Smoke_sid_clientId$", + "$CLIENT_ASSERTION_PAR_JWT_NO_PURPOSE$" }); + + CLIENT_CONFIG_MAP.put("@NoTitleAndSubTitle", + new String[] { "$ID:CreateOIDCClient_with_purpose_title_and_subtitle_null_Smoke_sid_clientId$", + "$CLIENT_ASSERTION_PAR_JWT_NO_TITLE$" }); + + CLIENT_CONFIG_MAP.put("@EmptyTitleAndSubTitle", + new String[] { "$ID:CreateOIDCClient_with_purpose_title_and_subtitle_empty_Smoke_sid_clientId$", + "$CLIENT_ASSERTION_PAR_JWT_EMPTY_TITLE$" }); + + CLIENT_CONFIG_MAP.put("@SingleAuthFactor", + new String[] { "$ID:CreateOIDCClient_with_single_auth_factor_Smoke_sid_clientId$", + "$CLIENT_ASSERTION_PAR_JWT_SINGLE_ACR_VALUE$" }); + } + @Before(order = 2) public void beforeAll(Scenario scenario) { if (isMobileMode.get() == null) { @@ -97,6 +132,18 @@ public void beforeAll(Scenario scenario) { } isKnownIssueScenario.set(false); + String pluginName = EsignetUtil.getPluginName(); + + if ("mosipid".equalsIgnoreCase(pluginName)) { + Set skipTags = new HashSet<>(CLIENT_CONFIG_MAP.keySet()); + + for (String tag : scenario.getSourceTagNames()) { + if (skipTags.contains(tag)) { + throw new SkipException("Skipped for mosipid"); + } + } + } + totalCount++; String browser = BaseTestUtil.getBrowserForScenario(scenario); // Start logging for the scenario String lang = BaseTestUtil.getThreadLocalLanguage(); @@ -129,11 +176,23 @@ public void beforeAll(Scenario scenario) { String baseUrl = EsignetConfigManager.getproperty("eSignetbaseurl"); String template = EsignetConfigManager.getproperty("authorizeUrlTemplate"); - String requestUri = EsignetUtil.generateParRequestUri(); + String clientIdKey = "$ID:CreateOIDCClient_all_Valid_Smoke_sid_clientId$"; + String clientAssertion = "$CLIENT_ASSERTION_PAR_JWT$"; + + for (String tag : scenario.getSourceTagNames()) { + if (CLIENT_CONFIG_MAP.containsKey(tag)) { + String[] values = CLIENT_CONFIG_MAP.get(tag); + clientIdKey = values[0]; + clientAssertion = values[1]; + break; + } + } + + String requestUri = EsignetUtil.generateParRequestUri(clientIdKey, clientAssertion); - String updatedTemplate = template.replace("$REQUEST_URI$", requestUri); + String clientId = AdminTestUtil.replaceIdWithAutogeneratedId(clientIdKey, "$ID:"); - updatedTemplate = AdminTestUtil.replaceIdWithAutogeneratedId(updatedTemplate, "$ID:"); + String updatedTemplate = template.replace("$REQUEST_URI$", requestUri).replace("$CLIENT_ID$", clientId); String authorizeUrl = baseUrl + updatedTemplate; diff --git a/ui-test/src/main/java/pages/ConsentPage.java b/ui-test/src/main/java/pages/ConsentPage.java index b383fb03a..6e51d1e84 100644 --- a/ui-test/src/main/java/pages/ConsentPage.java +++ b/ui-test/src/main/java/pages/ConsentPage.java @@ -120,6 +120,17 @@ public ConsentPage(WebDriver driver) { @FindBy(xpath = "//p[@class='text-[#4E4E4E] font-semibold']") WebElement actionMessage; + @FindBy(id = "login-header") + WebElement loginTitle; + + @FindBy(id = "login-subheader") + WebElement loginSubTitle; + + @FindBy(xpath = "//h1[@class='text-base leading-5 font-sans font-medium my-2']") + WebElement selectPreferredModeHeader; + + @FindBy(xpath = "//div[@class='inline mx-2 font-semibold my-3']") + WebElement selectPreferredIdHeader; @FindBy(xpath = "//div[@class='header my-2']") WebElement headerInConsentUpdateProfileScreen; @@ -377,6 +388,34 @@ public boolean isVerifyOtpButtonEnabled() { return isButtonEnabled(verifyOtpButton, "Verified otp verification button is enabled"); } + public boolean isLoginWithOtpDisplayed(String expectedText) { + return isElementDisplayed(loginWithOtpButton) && loginWithOtpButton.getText().trim().startsWith(expectedText); + } + + public boolean isLoginTitleDisplayed() { + return isElementDisplayed(loginTitle); + } + + public boolean isLoginSubTitleDisplayed() { + return isElementDisplayed(loginSubTitle); + } + + public String getLoginTitleText() { + return loginTitle.getText().trim(); + } + + public String getLoginSubTitleText() { + return loginSubTitle.getText().trim(); + } + + public String getSelectPreferredModeHeaderText() { + return selectPreferredModeHeader.getText().trim(); + } + + public String getSelectPreferredIdHeaderText() { + return selectPreferredIdHeader.getText().trim(); + } + public boolean isHeaderInConsentUpdateProfileScreenVisible() { return isElementVisible(headerInConsentUpdateProfileScreen, "Verified header in consent update profile screen"); } diff --git a/ui-test/src/main/java/pages/VideoPreviewPage.java b/ui-test/src/main/java/pages/VideoPreviewPage.java index f203c2b6d..8e8258991 100644 --- a/ui-test/src/main/java/pages/VideoPreviewPage.java +++ b/ui-test/src/main/java/pages/VideoPreviewPage.java @@ -1,6 +1,5 @@ package pages; -import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; diff --git a/ui-test/src/main/java/stepdefinitions/ConsentStepDefinition.java b/ui-test/src/main/java/stepdefinitions/ConsentStepDefinition.java index 1acd5ddb9..31ff7744c 100644 --- a/ui-test/src/main/java/stepdefinitions/ConsentStepDefinition.java +++ b/ui-test/src/main/java/stepdefinitions/ConsentStepDefinition.java @@ -24,8 +24,11 @@ import pages.LoginOptionsPage; import pages.SignUpPage; import pages.SignupFormDynamicFiller; +import utils.BaseTestUtil; +import utils.ClaimsUtil; import utils.EsignetUtil; import utils.EsignetUtil.RegisteredDetails; +import utils.ResourceBundleLoader; public class ConsentStepDefinition { @@ -352,17 +355,120 @@ public void verifyTheActionMessage() { public void verifyTheTimerInConsentScreen() { Assert.assertTrue(consentPage.isTimerDisplayed(), "The timer is not displayed in the consent screen"); } - + @Then("verify the otp verification button is disabled on the verification screen") public void verifyOtpVerificationButtonIsDisabled() { - Assert.assertFalse(consentPage.isVerifyOtpButtonEnabled(), - "Otp verification button is enabled"); + Assert.assertFalse(consentPage.isVerifyOtpButtonEnabled(), "Otp verification button is enabled"); } - + @Then("verify the otp verification button is enabled on the verification screen") public void verifyOtpVerificationButtonIsEnabled() { - Assert.assertTrue(consentPage.isVerifyOtpButtonEnabled(), - "Otp verification button is not enabled"); + Assert.assertTrue(consentPage.isVerifyOtpButtonEnabled(), "Otp verification button is not enabled"); + } + + @When("user creates the client with purpose type login") + public void userCreateClientIdPurposeLogin() { + // Purpose is already handled via scenario tags in BaseTest + } + + @Then("all auth factors should start with login") + public void verifyLoginPurposeReflectedInUI() { + String expectedText = ResourceBundleLoader.getPrefixText("otp.login_with_id"); + Assert.assertTrue(consentPage.isLoginWithOtpDisplayed(expectedText), + "Expected text not displayed: " + expectedText); + } + + @When("user creates the client without purpose field") + public void userCreateClientIdWithoutPurpose() { + // Purpose is already handled via scenario tags in BaseTest + } + + @When("user creates the client with purpose type link") + public void userCreateClientIdPurposeLink() { + // Purpose is already handled via scenario tags in BaseTest + } + + @Then("all auth factors should start with link") + public void verifyLinkPurposeReflectedInUI() { + String expectedText = ResourceBundleLoader.getPrefixText("otp.link_using_id"); + Assert.assertTrue(consentPage.isLoginWithOtpDisplayed(expectedText), + "Expected text not displayed: " + expectedText); + } + + @When("user creates the client with purpose type verify") + public void userCreateClientIdPurposeVerify() { + // Purpose is already handled via scenario tags in BaseTest + } + + @Then("all auth factors should start with verify") + public void validateVerifyPurposeReflectedInUI() { + String expectedText = ResourceBundleLoader.getPrefixText("otp.verify_with_id"); + Assert.assertTrue(consentPage.isLoginWithOtpDisplayed(expectedText), + "Expected text not displayed: " + expectedText); + } + + @When("user creates the client with purpose type none") + public void userCreateClientIdPurposeNone() { + // Purpose is already handled via scenario tags in BaseTest + } + + @Then("verify no title or subtitle should be displayed") + public void verifyTitleNotDisplayed() { + Assert.assertFalse(consentPage.isLoginTitleDisplayed(), "Title is displayed"); + Assert.assertFalse(consentPage.isLoginSubTitleDisplayed(), "Subtitle is displayed"); + } + + @Then("verify title and subtitle should be displayed as per text given during client creation") + public void verifyDefaultLoginTitleAndSubtitle() { + Assert.assertTrue(consentPage.getLoginTitleText().equals("Verify using eSignet")); + Assert.assertTrue(consentPage.getLoginSubTitleText().contains("is requesting authentication for verification")); + } + + @When("user creates the client with null title and subtitle values") + public void userCreateClientIdWithNullTitle() { + // Title is already handled via scenario tags in BaseTest + } + + @When("user creates the client with empty title and subtitle values") + public void userCreateClientIdWithEmptyTitle() { + // Title is already handled via scenario tags in BaseTest + } + + @Then("verify select preferred mode text is displayed") + public void verifySelectPreferredModeText() { + String expectedText = ResourceBundleLoader.get("signInOption.preferred_mode_to_continue"); + Assert.assertEquals(consentPage.getSelectPreferredModeHeaderText(), expectedText, "Expected text mismatch"); + } + + @Then("verify select preferred ID text based on purpose type when more than one auth factor is present") + public void verifySelectPreferredIdHeaderText() { + List authFactors = ClaimsUtil.getAuthFactors(); + Assert.assertFalse(authFactors.isEmpty(), "No auth factors were parsed from the authorize URL"); + + Assert.assertTrue(authFactors.size() > 1, "Expected multiple auth factors, got " + authFactors.size()); + String expectedText = ResourceBundleLoader.get("otp.login_with_id_multiple"); + Assert.assertEquals(consentPage.getSelectPreferredIdHeaderText(), expectedText, "Expected text mismatch"); + } + + @When("user creates the client with single auth factor") + public void userCreateClientIdWithSingleAuthFactor() { + // It is already handled via scenario tags in BaseTest + } + + @Then("verify select ID type text based on purpose type when one auth factor is displayed") + public void verifySelectIdTypeHeaderText() { + List authFactors = ClaimsUtil.getAuthFactors(); + Assert.assertFalse(authFactors.isEmpty(), "No auth factors were parsed from the authorize URL"); + + Assert.assertTrue(authFactors.size() == 1, "Expected multiple auth factors, got " + authFactors.size()); + String expectedText = ResourceBundleLoader.get("otp.login_with_id_multiple"); + Assert.assertEquals(consentPage.getSelectPreferredIdHeaderText(), expectedText, "Expected text mismatch"); + } + + @Then("verify select preferred ID text based on purpose type is displayed") + public void verifySelectPreferredIdHeaderTextDisplayed() { + String expectedText = ResourceBundleLoader.get("otp.login_with_id_multiple"); + Assert.assertEquals(consentPage.getSelectPreferredIdHeaderText(), expectedText, "Expected text mismatch"); } @Then("verify the header Attention in the consent to profile update screen") diff --git a/ui-test/src/main/java/stepdefinitions/InvalidUrlStepDefinition.java b/ui-test/src/main/java/stepdefinitions/InvalidUrlStepDefinition.java index d2a75916b..af6d743ef 100644 --- a/ui-test/src/main/java/stepdefinitions/InvalidUrlStepDefinition.java +++ b/ui-test/src/main/java/stepdefinitions/InvalidUrlStepDefinition.java @@ -139,7 +139,8 @@ public void verifyPageDoesNotExistErrorDisplayed() { public void userModifiesAuthorizeValue() throws Exception { String baseUrl = EsignetConfigManager.getproperty("eSignetbaseurl"); String template = EsignetConfigManager.getproperty("authorizeUrlTemplate"); - String requestUri = EsignetUtil.generateParRequestUri(); + String requestUri = EsignetUtil.generateParRequestUri("$ID:CreateOIDCClient_all_Valid_Smoke_sid_clientId$", + "$CLIENT_ASSERTION_PAR_JWT$"); String updatedTemplate = template.replace("$REQUEST_URI$", requestUri); updatedTemplate = AdminTestUtil.replaceIdWithAutogeneratedId(updatedTemplate, "$ID:"); String url = baseUrl + updatedTemplate; @@ -152,7 +153,8 @@ public void userModifiesAuthorizeValue() throws Exception { public void userRemovesAuthorizeInUrl() throws Exception { String baseUrl = EsignetConfigManager.getproperty("eSignetbaseurl"); String template = EsignetConfigManager.getproperty("authorizeUrlTemplate"); - String requestUri = EsignetUtil.generateParRequestUri(); + String requestUri = EsignetUtil.generateParRequestUri("$ID:CreateOIDCClient_all_Valid_Smoke_sid_clientId$", + "$CLIENT_ASSERTION_PAR_JWT$"); String updatedTemplate = template.replace("$REQUEST_URI$", requestUri); updatedTemplate = AdminTestUtil.replaceIdWithAutogeneratedId(updatedTemplate, "$ID:"); String url = baseUrl + updatedTemplate; diff --git a/ui-test/src/main/java/utils/EsignetUtil.java b/ui-test/src/main/java/utils/EsignetUtil.java index 3863679a2..daad5a15b 100644 --- a/ui-test/src/main/java/utils/EsignetUtil.java +++ b/ui-test/src/main/java/utils/EsignetUtil.java @@ -13,8 +13,11 @@ import java.util.Map; import java.util.Optional; import java.util.Random; +import java.util.Set; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ThreadLocalRandom; +import java.util.function.Consumer; import javax.ws.rs.core.MediaType; @@ -71,7 +74,21 @@ public class EsignetUtil extends AdminTestUtil { private static String partnerCookie = null; private static String mobileAuthCookie = null; protected static boolean triggerESignetKeyGenForPAR = true; + protected static boolean triggerESignetKeyGenForPARPurposeLogin = true; + protected static boolean triggerESignetKeyGenForPARPurposeLink = true; + protected static boolean triggerESignetKeyGenForPARPurposeNone = true; + protected static boolean triggerESignetKeyGenForPARNoPurpose = true; + protected static boolean triggerESignetKeyGenForPARNoTitle = true; + protected static boolean triggerESignetKeyGenForPAREmptyTitle = true; + protected static boolean triggerESignetKeyGenForPARSingleAcrValue = true; protected static final String OIDC_JWK_FOR_PAR = "oidcJWKForPAR"; + protected static final String OIDC_JWK_FOR_PAR_PURPOSE_LOGIN = "oidcJWKForPARPurposeLogin"; + protected static final String OIDC_JWK_FOR_PAR_PURPOSE_LINK = "oidcJWKForPARPurposeLink"; + protected static final String OIDC_JWK_FOR_PAR_PURPOSE_NONE = "oidcJWKForPARPurposeNone"; + protected static final String OIDC_JWK_FOR_PAR_NO_PURPOSE = "oidcJWKForPARNoPurposeType"; + protected static final String OIDC_JWK_FOR_PAR_NO_TITLE = "oidcJWKForPARNoTitle"; + protected static final String OIDC_JWK_FOR_PAR_EMPTY_TITLE = "oidcJWKForPAREmptyTitle"; + protected static final String OIDC_JWK_FOR_PAR_SINGLE_ACR_VALUE = "oidcJWKForPARSingleAcrValue"; protected static RSAKey oidc_JWK_Key_For_PAR = null; protected static final String CLAIMS_REQUEST = "config/claims.json"; @@ -663,6 +680,62 @@ private static void setTriggerESignetKeyGenForPAR(boolean value) { triggerESignetKeyGenForPAR = value; } + private static boolean getTriggerESignetKeyGenForPARPurposeLogin() { + return triggerESignetKeyGenForPARPurposeLogin; + } + + private static void setTriggerESignetKeyGenForPARPurposeLogin(boolean value) { + triggerESignetKeyGenForPARPurposeLogin = value; + } + + private static boolean getTriggerESignetKeyGenForPARPurposeLink() { + return triggerESignetKeyGenForPARPurposeLink; + } + + private static void setTriggerESignetKeyGenForPARPurposeLink(boolean value) { + triggerESignetKeyGenForPARPurposeLink = value; + } + + private static boolean getTriggerESignetKeyGenForPARPurposeNone() { + return triggerESignetKeyGenForPARPurposeNone; + } + + private static void setTriggerESignetKeyGenForPARPurposeNone(boolean value) { + triggerESignetKeyGenForPARPurposeNone = value; + } + + private static boolean getTriggerESignetKeyGenForPARNoPurpose() { + return triggerESignetKeyGenForPARNoPurpose; + } + + private static void setTriggerESignetKeyGenForPARNoPurpose(boolean value) { + triggerESignetKeyGenForPARNoPurpose = value; + } + + private static boolean getTriggerESignetKeyGenForPARNoTitle() { + return triggerESignetKeyGenForPARNoTitle; + } + + private static void setTriggerESignetKeyGenForPARNoTitle(boolean value) { + triggerESignetKeyGenForPARNoTitle = value; + } + + private static boolean getTriggerESignetKeyGenForPARSingleAcrValue() { + return triggerESignetKeyGenForPARSingleAcrValue; + } + + private static void setTriggerESignetKeyGenForPARSingleAcrValue(boolean value) { + triggerESignetKeyGenForPARSingleAcrValue = value; + } + + private static boolean getTriggerESignetKeyGenForPAREmptyTitle() { + return triggerESignetKeyGenForPAREmptyTitle; + } + + private static void setTriggerESignetKeyGenForPAREmptyTitle(boolean value) { + triggerESignetKeyGenForPAREmptyTitle = value; + } + public static void getSupportedLanguage() { if (EsignetConfigManager.getproperty("esignetSupportedLanguage") != null) { @@ -689,15 +762,74 @@ public static String inputstringKeyWordHandler(String jsonString, String testCas String.valueOf(Calendar.getInstance().getTimeInMillis())); } - if (jsonString.contains("$CLIENT_ASSERTION_PAR_JWT$")) { - String oidcJWKKeyString = JWKKeyUtil.getJWKKey(OIDC_JWK_FOR_PAR); - logger.info("oidcJWKKeyString =" + oidcJWKKeyString); + jsonString = processClientAssertion(jsonString, "$CLIENT_ASSERTION_PAR_JWT$", OIDC_JWK_FOR_PAR); + + jsonString = processJWKKey(jsonString, "$OIDC_JWK_KEY_PAR$", OIDC_JWK_FOR_PAR); + + // PURPOSE_LOGIN + jsonString = processClientAssertion(jsonString, "$CLIENT_ASSERTION_PAR_JWT_PURPOSE_LOGIN$", + OIDC_JWK_FOR_PAR_PURPOSE_LOGIN); + + jsonString = processJWKKey(jsonString, "$OIDC_JWK_KEY_PAR_PURPOSE_LOGIN$", OIDC_JWK_FOR_PAR_PURPOSE_LOGIN); + + // PURPOSE_LINK + jsonString = processClientAssertion(jsonString, "$CLIENT_ASSERTION_PAR_JWT_PURPOSE_LINK$", + OIDC_JWK_FOR_PAR_PURPOSE_LINK); + + jsonString = processJWKKey(jsonString, "$OIDC_JWK_KEY_PAR_PURPOSE_LINK$", OIDC_JWK_FOR_PAR_PURPOSE_LINK); + + // PURPOSE_NONE + jsonString = processClientAssertion(jsonString, "$CLIENT_ASSERTION_PAR_JWT_PURPOSE_NONE$", + OIDC_JWK_FOR_PAR_PURPOSE_NONE); + + jsonString = processJWKKey(jsonString, "$OIDC_JWK_KEY_PAR_PURPOSE_NONE$", OIDC_JWK_FOR_PAR_PURPOSE_NONE); + + // NO PURPOSE + jsonString = processClientAssertion(jsonString, "$CLIENT_ASSERTION_PAR_JWT_NO_PURPOSE$", + OIDC_JWK_FOR_PAR_NO_PURPOSE); + + jsonString = processJWKKey(jsonString, "$OIDC_JWK_KEY_PAR_NO_PURPOSE$", OIDC_JWK_FOR_PAR_NO_PURPOSE); + + // NO TITLE + jsonString = processClientAssertion(jsonString, "$CLIENT_ASSERTION_PAR_JWT_NO_TITLE$", + OIDC_JWK_FOR_PAR_NO_TITLE); + + jsonString = processJWKKey(jsonString, "$OIDC_JWK_KEY_PAR_NO_TITLE$", OIDC_JWK_FOR_PAR_NO_TITLE); + + // EMPTY TITLE + jsonString = processClientAssertion(jsonString, "$CLIENT_ASSERTION_PAR_JWT_EMPTY_TITLE$", + OIDC_JWK_FOR_PAR_EMPTY_TITLE); + + jsonString = processJWKKey(jsonString, "$OIDC_JWK_KEY_PAR_EMPTY_TITLE$", OIDC_JWK_FOR_PAR_EMPTY_TITLE); + + // SINGLE AUTH FACTOR + jsonString = processClientAssertion(jsonString, "$CLIENT_ASSERTION_PAR_JWT_SINGLE_ACR_VALUE$", + OIDC_JWK_FOR_PAR_SINGLE_ACR_VALUE); + + jsonString = processJWKKey(jsonString, "$OIDC_JWK_KEY_PAR_SINGLE_ACR_VALUE$", + OIDC_JWK_FOR_PAR_SINGLE_ACR_VALUE); + + if (jsonString.contains("$ESIGNET_REDIRECT_URI$")) { + jsonString = replaceKeywordWithValue(jsonString, "$ESIGNET_REDIRECT_URI$", + EsignetConfigManager.getproperty("baseurl") + "userprofile"); + } + + return jsonString; + + } + + private static String processClientAssertion(String jsonString, String placeholder, String jwkKeyName) { + + if (jsonString.contains(placeholder)) { + + String keyString = JWKKeyUtil.getJWKKey(jwkKeyName); + RSAKey rsaKey; + try { - oidc_JWK_Key_For_PAR = RSAKey.parse(oidcJWKKeyString); - logger.info("oidc_JWK_Key_For_PAR =" + oidc_JWK_Key_For_PAR); - } catch (java.text.ParseException e) { - logger.error(e.getMessage()); - throw new RuntimeException("Failed to parse OIDC JWK key for PAR", e); + rsaKey = RSAKey.parse(keyString); + } catch (Exception e) { + throw new RuntimeException( + "Failed to parse JWK for placeholder " + placeholder + " (key=" + jwkKeyName + ")", e); } JSONObject root = new JSONObject(jsonString); @@ -710,34 +842,24 @@ public static String inputstringKeyWordHandler(String jsonString, String testCas jsonString = root.toString(); } - String tempUrl = getValueFromEsignetWellKnownEndPoint(audKey, EsignetConfigManager.getEsignetBaseUrl()); + String url = getValueFromEsignetWellKnownEndPoint(audKey, EsignetConfigManager.getEsignetBaseUrl()); if (clientId != null) { - jsonString = replaceKeywordWithValue(jsonString, "$CLIENT_ASSERTION_PAR_JWT$", - signJWKKey(clientId, oidc_JWK_Key_For_PAR, tempUrl)); - } else { - logger.error("Client ID not found in JSON for $CLIENT_ASSERTION_PAR_JWT$."); + jsonString = replaceKeywordWithValue(jsonString, placeholder, signJWKKey(clientId, rsaKey, url)); } } - if (jsonString.contains("$OIDC_JWK_KEY_PAR$")) { - String jwkKey = ""; - if (getTriggerESignetKeyGenForPAR()) { - jwkKey = JWKKeyUtil.generateAndCacheJWKKey(OIDC_JWK_FOR_PAR); - setTriggerESignetKeyGenForPAR(false); - } else { - jwkKey = JWKKeyUtil.getJWKKey(OIDC_JWK_FOR_PAR); - } - jsonString = replaceKeywordWithValue(jsonString, "$OIDC_JWK_KEY_PAR$", jwkKey); - } - - if (jsonString.contains("$ESIGNET_REDIRECT_URI$")) { - jsonString = replaceKeywordWithValue(jsonString, "$ESIGNET_REDIRECT_URI$", - EsignetConfigManager.getproperty("baseurl") + "userprofile"); - } - return jsonString; + } + + private static final Set generatedJwkKeys = ConcurrentHashMap.newKeySet(); + private static String processJWKKey(String jsonString, String placeholder, String jwkKeyName) { + if (!jsonString.contains(placeholder)) + return jsonString; + String jwkKey = generatedJwkKeys.add(jwkKeyName) ? JWKKeyUtil.generateAndCacheJWKKey(jwkKeyName) + : JWKKeyUtil.getJWKKey(jwkKeyName); + return replaceKeywordWithValue(jsonString, placeholder, jwkKey); } public static String getValueFromEsignetWellKnownEndPoint(String key, String baseURL) { @@ -950,7 +1072,8 @@ protected static Response postWithBodyAndCookieForAutoGeneratedIdForUrlEncoded(S } } - public static String generateParRequestUri() throws SecurityXSSException, JsonProcessingException { + public static String generateParRequestUri(String clientIdKey, String clientAssertionPlaceholder) + throws SecurityXSSException, JsonProcessingException { String baseUrl = EsignetConfigManager.getproperty("eSignetbaseurl"); String parUrl = baseUrl + "/v1/esignet/oauth/par"; @@ -961,8 +1084,10 @@ public static String generateParRequestUri() throws SecurityXSSException, JsonPr requestBody.put("display", display); requestBody.put("response_type", responseType); requestBody.put("nonce", "$UNIQUENONCEVALUEFORESIGNET$"); - requestBody.put("client_id", AdminTestUtil - .replaceIdWithAutogeneratedId("$ID:CreateOIDCClient_all_Valid_Smoke_sid_clientId$", "$ID:")); + if (clientIdKey == null || clientIdKey.isEmpty()) { + clientIdKey = "$ID:CreateOIDCClient_all_Valid_Smoke_sid_clientId$"; + } + requestBody.put("client_id", AdminTestUtil.replaceIdWithAutogeneratedId(clientIdKey, "$ID:")); requestBody.put("requestTime", "$TIMESTAMP$"); requestBody.put("client_assertion_type", client_assertion_type); requestBody.put("claim_locales", claim_locales); @@ -972,7 +1097,7 @@ public static String generateParRequestUri() throws SecurityXSSException, JsonPr "mosip:idp:acr:generated-code mosip:idp:acr:biometrics mosip:idp:acr:linked-wallet mosip:idp:acr:password"); requestBody.put("redirect_uri", "$ESIGNET_REDIRECT_URI$"); requestBody.put("state", state); - requestBody.put("client_assertion", "$CLIENT_ASSERTION_PAR_JWT$"); + requestBody.put("client_assertion", clientAssertionPlaceholder); requestBody.put("prompt", prompt); requestBody.put("aud_key", aud_key); diff --git a/ui-test/src/main/java/utils/ResourceBundleLoader.java b/ui-test/src/main/java/utils/ResourceBundleLoader.java index ac78eb3ca..5575fbbbf 100644 --- a/ui-test/src/main/java/utils/ResourceBundleLoader.java +++ b/ui-test/src/main/java/utils/ResourceBundleLoader.java @@ -41,7 +41,7 @@ private static void loadResourceBundleJson(String currentLang) { logger.warn("No ISO mapping found for language: " + currentLang + ", falling back to: " + currentLang); twoLetterCode = currentLang; } - String url = EsignetConfigManager.getproperty("baseurl") + "/locales/" + twoLetterCode + ".json"; + String url = EsignetConfigManager.getproperty("eSignetbaseurl") + "/locales/" + twoLetterCode + ".json"; String jsonContent = downloadJson(url); Map nestedMap = new ObjectMapper().readValue(jsonContent, new TypeReference<>() { @@ -74,4 +74,12 @@ private static void flatten(Map source, String prefix, Map