Skip to content

Conversation

@HasiniSama
Copy link
Contributor

@HasiniSama HasiniSama commented Dec 22, 2025

Purpose

$subject

Resolves: wso2/product-is#26137

Add the below config to enable this:

[api.filters]
single_character_wildcard = "_"

Before:

Screenshot 2025-12-01 at 03 49 02 Screenshot 2025-12-01 at 03 50 31

After:

Screenshot 2025-12-01 at 03 49 20 Screenshot 2025-12-01 at 03 50 38 Screenshot 2025-12-01 at 03 50 52

Summary by CodeRabbit

  • New Features

    • Added configurable single-character wildcard support for API filtering operations, enabling customizable wildcard behavior in search and filter queries.
  • Bug Fixes

    • Enhanced SQL filter queries with proper wildcard escaping across search, filtering, and data retrieval operations to improve reliability and prevent unintended pattern matching.

✏️ Tip: You can customize this high-level summary in your review settings.

Comment on lines 126 to 132
if (StringUtils.isNotBlank(attributeName) && StringUtils.isNotBlank(value) && StringUtils
.isNotBlank(operation)) {
// Escape SQL wildcards for operations that use LIKE clause.
if (operation.equals(SW) || operation.equals(EW) || operation.equals(CO)) {
value = IdentityUtil.processSingleCharWildcard(value);
}
switch (operation) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log Improvement Suggestion No: 1

Suggested change
if (StringUtils.isNotBlank(attributeName) && StringUtils.isNotBlank(value) && StringUtils
.isNotBlank(operation)) {
// Escape SQL wildcards for operations that use LIKE clause.
if (operation.equals(SW) || operation.equals(EW) || operation.equals(CO)) {
value = IdentityUtil.processSingleCharWildcard(value);
}
switch (operation) {
if (StringUtils.isNotBlank(attributeName) && StringUtils.isNotBlank(value) && StringUtils
.isNotBlank(operation)) {
// Escape SQL wildcards for operations that use LIKE clause.
if (operation.equals(SW) || operation.equals(EW) || operation.equals(CO)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Processing SQL wildcard escaping for operation: " + operation + ", attribute: " + attributeName);
}
value = IdentityUtil.processSingleCharWildcard(value);
}

Comment on lines 3914 to 3916
FilterData filterData = new FilterData();

if (StringUtils.isBlank(filter) || filter.equals(ASTERISK)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log Improvement Suggestion No: 3

Suggested change
FilterData filterData = new FilterData();
if (StringUtils.isBlank(filter) || filter.equals(ASTERISK)) {
private FilterData getFilterDataForDBQuery(String filter) throws IdentityApplicationManagementException {
FilterData filterData = new FilterData();
if (log.isDebugEnabled()) {
log.debug("Processing filter query: " + filter);
}

Comment on lines +4007 to +4010
if (FILTER_STARTS_WITH.equals(searchOperation) || FILTER_ENDS_WITH.equals(searchOperation) ||
FILTER_CONTAINS.equals(searchOperation)) {
formattedFilterValue = IdentityUtil.processSingleCharWildcard(formattedFilterValue);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log Improvement Suggestion No: 4

Suggested change
if (FILTER_STARTS_WITH.equals(searchOperation) || FILTER_ENDS_WITH.equals(searchOperation) ||
FILTER_CONTAINS.equals(searchOperation)) {
formattedFilterValue = IdentityUtil.processSingleCharWildcard(formattedFilterValue);
}
if (FILTER_STARTS_WITH.equals(searchOperation) || FILTER_ENDS_WITH.equals(searchOperation) ||
FILTER_CONTAINS.equals(searchOperation)) {
formattedFilterValue = IdentityUtil.processSingleCharWildcard(formattedFilterValue);
if (log.isDebugEnabled()) {
log.debug("Escaped SQL wildcards for operation: " + searchOperation);
}
}

* @param value The user input value to process.
* @return The processed value with wildcard handling applied.
*/
public static String processSingleCharWildcard(String value) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log Improvement Suggestion No: 5

Suggested change
public static String processSingleCharWildcard(String value) {
public static String processSingleCharWildcard(String value) {
log.debug("Processing single character wildcard for input value");

Comment on lines +2397 to +2399
if (StringUtils.isNotBlank(wildcardChar) && wildcardChar.length() == 1) {
escaped = escaped.replace(wildcardChar, UNDERSCORE);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log Improvement Suggestion No: 6

Suggested change
if (StringUtils.isNotBlank(wildcardChar) && wildcardChar.length() == 1) {
escaped = escaped.replace(wildcardChar, UNDERSCORE);
}
if (StringUtils.isNotBlank(wildcardChar) && wildcardChar.length() == 1) {
escaped = escaped.replace(wildcardChar, UNDERSCORE);
}
if (log.isDebugEnabled()) {
log.debug("Processed wildcard value with wildcard character: " + wildcardChar);
}

Comment on lines 1007 to 1010
} else if (IdPManagementConstants.SW.equals(operation)) {
filter.append(attributeName).append(" like ? AND ");
value = IdentityUtil.processSingleCharWildcard(value);
filter.append(attributeName).append(" like ? ESCAPE '\\' AND ");
filterQueryBuilder.setFilterAttributeValue(value + "%");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log Improvement Suggestion No: 7

Suggested change
} else if (IdPManagementConstants.SW.equals(operation)) {
filter.append(attributeName).append(" like ? AND ");
value = IdentityUtil.processSingleCharWildcard(value);
filter.append(attributeName).append(" like ? ESCAPE '\\' AND ");
filterQueryBuilder.setFilterAttributeValue(value + "%");
} else if (IdPManagementConstants.SW.equals(operation)) {
value = IdentityUtil.processSingleCharWildcard(value);
if (log.isDebugEnabled()) {
log.debug("Processing SW filter for attribute: " + attributeName);
}
filter.append(attributeName).append(" like ? ESCAPE '\\' AND ");

@coderabbitai
Copy link

coderabbitai bot commented Dec 22, 2025

Walkthrough

This PR addresses improper handling of underscore characters in SQL LIKE queries by introducing centralized wildcard character escaping. It adds utility methods to normalize filter values, applies ESCAPE clauses to SQL statements, and introduces a configurable single-character wildcard setting across the identity management layer.

Changes

Cohort / File(s) Summary
Wildcard Escaping Utility & Constants
components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityUtil.java, components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityCoreConstants.java
Introduces new public method processSingleCharWildcard(String value) to escape and normalize wildcard characters. Adds constants UNDERSCORE and SINGLE_CHARACTER_WILDCARD for configurable wildcard handling.
DAO Layer Wildcard Handling
components/api-resource-mgt/.../FilterQueriesUtil.java, components/application-mgt/.../ApplicationDAOImpl.java, components/idp-mgt/.../IdPManagementDAO.java
Updates LIKE-based filter operations (SW, EW, CO) to preprocess values via IdentityUtil.processSingleCharWildcard() and appends SQL ESCAPE clauses (ESCAPE '\\') to filter queries for proper wildcard escaping.
Test Updates
components/application-mgt/.../ApplicationManagementServiceImplTest.java
Extends data provider with new filterValue parameter, updates test methods testGetApplicationBasicInfoWithFilterExcludingSystemPortals and testGetCountOfApplicationsWithFilterExcludingSystemPortals to use wildcard-processed filter values.
Configuration
features/identity-core/.../identity.xml.j2, features/identity-core/.../org.wso2.carbon.identity.core.server.feature.default.json
Adds new APIFiltering element with SingleCharacterWildcard configuration bound to api.filters.single_character_wildcard setting.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Wildcard escaping logic: Review the new processSingleCharWildcard() method in IdentityUtil.java carefully to verify it correctly escapes backslashes and underscores before replacements.
  • ESCAPE clause consistency: Verify that all LIKE operations across FilterQueriesUtil.java, ApplicationDAOImpl.java, and IdPManagementDAO.java apply the ESCAPE clause and value preprocessing uniformly.
  • Test coverage alignment: Ensure test cases in ApplicationManagementServiceImplTest.java properly validate wildcard-escaped scenarios and that the new filterValue parameter correctly maps through processSingleCharWildcard().
  • Configuration integration: Confirm the new configuration properties in both XML and JSON are consistent and properly connected to the utility method.

Poem

🐰 Underscores no longer wildly roam,
Escaped and bound, they've found a home,
With backslash guards and SQL clear,
Precise filters now appear! ✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description includes Purpose with issue link, configuration details, and visual before/after screenshots. However, Goals, Approach, User stories, Release note, Documentation, Training, Certification, Marketing, Automation tests details, Security checks, Samples, Related PRs, Migrations, Test environment, and Learning sections are missing or incomplete. Add missing sections from the template: Goals, Approach, User stories, Release note, Documentation, Training, Certification, Marketing, Automation tests, Security checks, Samples, Related PRs, Migrations, Test environment, and Learning to provide complete context.
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding SQL wildcard escaping for underscore and implementing custom wildcard support, which aligns with the PR's objectives and code modifications.
Linked Issues check ✅ Passed The PR successfully implements SQL wildcard escaping and configurable single-character wildcard support (via IdentityUtil.processSingleCharWildcard and new configuration api.filters.single_character_wildcard) to prevent underscore from being treated as a wildcard in user searches, directly addressing issue #26137 requirements.
Out of Scope Changes check ✅ Passed All code changes are directly related to implementing SQL wildcard escaping and custom wildcard support as specified in #26137. Updates to FilterQueriesUtil, ApplicationDAOImpl, IdPManagementDAO, IdentityUtil, and configuration files are all in-scope for the stated objective.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.40.0)
components/application-mgt/org.wso2.carbon.identity.application.mgt/src/main/java/org/wso2/carbon/identity/application/mgt/dao/impl/ApplicationDAOImpl.java
components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@wso2-engineering wso2-engineering bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI Agent Log Improvement Checklist

⚠️ Warning: AI-Generated Review Comments

  • The log-related comments and suggestions in this review were generated by an AI tool to assist with identifying potential improvements. Purpose of reviewing the code for log improvements is to improve the troubleshooting capabilities of our products.
  • Please make sure to manually review and validate all suggestions before applying any changes. Not every code suggestion would make sense or add value to our purpose. Therefore, you have the freedom to decide which of the suggestions are helpful.

✅ Before merging this pull request:

  • Review all AI-generated comments for accuracy and relevance.
  • Complete and verify the table below. We need your feedback to measure the accuracy of these suggestions and the value they add. If you are rejecting a certain code suggestion, please mention the reason briefly in the suggestion for us to capture it.
Comment Accepted (Y/N) Reason
#### Log Improvement Suggestion No: 1
#### Log Improvement Suggestion No: 3
#### Log Improvement Suggestion No: 4
#### Log Improvement Suggestion No: 5
#### Log Improvement Suggestion No: 6
#### Log Improvement Suggestion No: 7

@sonarqubecloud
Copy link

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
components/application-mgt/org.wso2.carbon.identity.application.mgt/src/test/java/org/wso2/carbon/identity/application/mgt/ApplicationManagementServiceImplTest.java (1)

173-189: Fix DataProvider argument shape for wildcard tests; consider tightening behavior coverage.

There is a hard bug in the updated DataProvider:

  • getAppsExcludingSystemPortalsDataProvider now returns rows of different lengths:
    • First two rows: { APPLICATION_NAME_FILTER_1, 1 }, { APPLICATION_NAME_FILTER_3, 0 } (2 elements).
    • Last two rows: { APPLICATION_NAME_FILTER_1, APPLICATION_FILTER_VALUE_1, 1 }, { APPLICATION_NAME_FILTER_3, APPLICATION_FILTER_VALUE_3, 0 } (3 elements).
  • But both consuming tests now have the signature (String filter, String filterValue, int expectedResult):
    • testGetApplicationBasicInfoWithFilterExcludingSystemPortals
    • testGetCountOfApplicationsWithFilterExcludingSystemPortals

With TestNG, this will fail at runtime because the first two rows don’t provide enough arguments for the method parameters.

To fix this, make all rows 3‑tuples. For example:

Suggested DataProvider fix
-    private static final String APPLICATION_NAME_FILTER_3 = "name ew application3";
-    private static final String APPLICATION_FILTER_VALUE_1 = "*application1";
-    private static final String APPLICATION_FILTER_VALUE_3 = "*application3";
+    private static final String APPLICATION_NAME_FILTER_3 = "name ew application3";
+    private static final String APPLICATION_FILTER_VALUE_1 = "*application1";
+    private static final String APPLICATION_FILTER_VALUE_3 = "*application3";
@@
     @DataProvider(name = "getAppsExcludingSystemPortalsDataProvider")
     public Object[][] getAppsExcludingSystemPortals() {

         return new Object[][]{
-                {APPLICATION_NAME_FILTER_1, 1},
-                {APPLICATION_NAME_FILTER_3, 0},
-                { APPLICATION_NAME_FILTER_1, APPLICATION_FILTER_VALUE_1, 1 },
-                { APPLICATION_NAME_FILTER_3, APPLICATION_FILTER_VALUE_3, 0 }
+                // No wildcard remapping case – processSingleCharWildcard should effectively be a no-op.
+                { APPLICATION_NAME_FILTER_1, "application1", 1 },
+                { APPLICATION_NAME_FILTER_3, "application3", 0 },
+                // Custom single-character wildcard case – mapped filter values.
+                { APPLICATION_NAME_FILTER_1, APPLICATION_FILTER_VALUE_1, 1 },
+                { APPLICATION_NAME_FILTER_3, APPLICATION_FILTER_VALUE_3, 0 }
         };
     }

This keeps your new APPLICATION_FILTER_VALUE_* constants in use while ensuring every row matches the test method signatures.

Optionally, you may also want to align the filter strings with the wildcard scenarios you’re trying to exercise (e.g., include the configured single‑character wildcard in the filter expression so that IdentityUtil.processSingleCharWildcard is exercised more realistically), but that can be done in a follow‑up.

Also applies to: 557-565, 601-618, 637-654

🧹 Nitpick comments (2)
components/application-mgt/org.wso2.carbon.identity.application.mgt/src/main/java/org/wso2/carbon/identity/application/mgt/dao/impl/ApplicationDAOImpl.java (1)

3991-4012: Check interaction between processSingleCharWildcard and resolveSQLFilter for underscore behavior.

The new flow for sw/ew/co is:

  1. Build a *-based mask (e.g., "*value*").
  2. Run IdentityUtil.processSingleCharWildcard(formattedFilterValue).
  3. Later, run resolveSQLFilter, which converts * → % and ? → _.

Based on the provided summary of IdentityUtil.processSingleCharWildcard(String value) (escaping underscores and mapping the configured SINGLE_CHARACTER_WILDCARD to _ when it is a non‑blank, non‑"_" character), this should:

  • Allow a configurable single‑character wildcard.
  • Escape literal underscores when the wildcard is configured to something else, so that ESCAPE '\' works as intended.

However, when SINGLE_CHARACTER_WILDCARD remains the default "_", the helper is described as returning the value unchanged, meaning underscores in searchValue will still act as SQL wildcards after resolveSQLFilter has turned * into %. If the product expectation is that underscores in search inputs stop behaving as wildcards without requiring an admin to change SINGLE_CHARACTER_WILDCARD, this may not fully address the original issue.

Please double‑check, with unit/integration tests, that for both:

  • default SINGLE_CHARACTER_WILDCARD configuration, and
  • a non‑underscore custom wildcard (e.g. ?),

the composed pattern (after processSingleCharWildcard + resolveSQLFilter) and the LIKE ... ESCAPE '\' clause yield the intended behavior for names containing underscores, and update docs if a config change is required to get non‑wildcard underscores.
Based on learnings from the provided IdentityUtil.processSingleCharWildcard summary.

components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityUtil.java (1)

120-128: Clarify SINGLE_CHARACTER_WILDCARD defaults vs processSingleCharWildcard behavior.

The implementation behavior is:

  • If value is blank → return as is.
  • If wildcardChar equals "_" → return value unchanged, so _ remains a SQL single‑char wildcard.
  • If wildcardChar is null/blank or any non‑"_":
    • All existing _ are escaped to \_ (with later ESCAPE '\').
    • If wildcardChar is a single non‑blank character, its occurrences are mapped to _, making that character the logical single‑char wildcard.

This is internally consistent, but the Javadoc currently states that "_" is the default and acts as a wildcard, while the “no config / empty config” case effectively makes _ literal (escaped). Given the PR goal is to fix underscore search behavior, please double‑check:

  • What value is actually configured by default for SINGLE_CHARACTER_WILDCARD in identity.xml / related config.
  • Whether the Javadoc should explicitly describe the “property absent/blank” case as the default behavior (escaping _), with "_" being an opt‑in for legacy wildcard semantics.

Adjusting either the docs or the default config to match the intended product behavior would avoid confusion for operators.

Also applies to: 2377-2401

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 601f2ee and aef229c.

📒 Files selected for processing (8)
  • components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/util/FilterQueriesUtil.java
  • components/application-mgt/org.wso2.carbon.identity.application.mgt/src/main/java/org/wso2/carbon/identity/application/mgt/dao/impl/ApplicationDAOImpl.java
  • components/application-mgt/org.wso2.carbon.identity.application.mgt/src/test/java/org/wso2/carbon/identity/application/mgt/ApplicationManagementServiceImplTest.java
  • components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityCoreConstants.java
  • components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityUtil.java
  • components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/org.wso2.carbon.identity.core.server.feature.default.json
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{py,java,ts,tsx,js,jsx,cs,go,rb,php}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

All public methods should have a docstring

Files:

  • components/application-mgt/org.wso2.carbon.identity.application.mgt/src/main/java/org/wso2/carbon/identity/application/mgt/dao/impl/ApplicationDAOImpl.java
  • components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityUtil.java
  • components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityCoreConstants.java
  • components/application-mgt/org.wso2.carbon.identity.application.mgt/src/test/java/org/wso2/carbon/identity/application/mgt/ApplicationManagementServiceImplTest.java
  • components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java
  • components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/util/FilterQueriesUtil.java
**/*.{py,java,ts,tsx,js,jsx,cs,go,rb,php,c,cpp,h,hpp}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{py,java,ts,tsx,js,jsx,cs,go,rb,php,c,cpp,h,hpp}: Comments should start with a space and first letter capitalized
Comments should always end with a period

Files:

  • components/application-mgt/org.wso2.carbon.identity.application.mgt/src/main/java/org/wso2/carbon/identity/application/mgt/dao/impl/ApplicationDAOImpl.java
  • components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityUtil.java
  • components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityCoreConstants.java
  • components/application-mgt/org.wso2.carbon.identity.application.mgt/src/test/java/org/wso2/carbon/identity/application/mgt/ApplicationManagementServiceImplTest.java
  • components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java
  • components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/util/FilterQueriesUtil.java
**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.java: If there's a string concatenation in a debug log, then having if (LOG.isDebugEnabled()) is mandatory to avoid unnecessary computation
For simple log messages (e.g., static strings or simple variable interpolation), you can use LOG.debug directly without the debug check

Files:

  • components/application-mgt/org.wso2.carbon.identity.application.mgt/src/main/java/org/wso2/carbon/identity/application/mgt/dao/impl/ApplicationDAOImpl.java
  • components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityUtil.java
  • components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityCoreConstants.java
  • components/application-mgt/org.wso2.carbon.identity.application.mgt/src/test/java/org/wso2/carbon/identity/application/mgt/ApplicationManagementServiceImplTest.java
  • components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java
  • components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/util/FilterQueriesUtil.java
**/*.{java,ts,tsx,js,jsx,py,cs,go,php}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{java,ts,tsx,js,jsx,py,cs,go,php}: Scrutinize all user-controlled input for potential SQL Injection, Cross-Site Scripting (XSS), or Command Injection
Ensure that no sensitive user data (e.g., PII, credentials) is being logged or sent in error messages

Files:

  • components/application-mgt/org.wso2.carbon.identity.application.mgt/src/main/java/org/wso2/carbon/identity/application/mgt/dao/impl/ApplicationDAOImpl.java
  • components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityUtil.java
  • components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityCoreConstants.java
  • components/application-mgt/org.wso2.carbon.identity.application.mgt/src/test/java/org/wso2/carbon/identity/application/mgt/ApplicationManagementServiceImplTest.java
  • components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java
  • components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/util/FilterQueriesUtil.java
**/*.{java,ts,tsx,js,jsx,py,cs,go,php,yml,yaml,json,env,properties,conf}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Search for and eliminate any exposed secrets like API keys, passwords, or private tokens

Files:

  • components/application-mgt/org.wso2.carbon.identity.application.mgt/src/main/java/org/wso2/carbon/identity/application/mgt/dao/impl/ApplicationDAOImpl.java
  • components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityUtil.java
  • components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityCoreConstants.java
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/org.wso2.carbon.identity.core.server.feature.default.json
  • components/application-mgt/org.wso2.carbon.identity.application.mgt/src/test/java/org/wso2/carbon/identity/application/mgt/ApplicationManagementServiceImplTest.java
  • components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java
  • components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/util/FilterQueriesUtil.java
**/*{DAO,Repository,Dao,dao}.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

All database queries should support the following database types: DB2, H2, MS SQL Server, MySQL, Oracle, and PostgreSQL

Files:

  • components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java
🧬 Code graph analysis (4)
components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityUtil.java (1)
components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityCoreConstants.java (1)
  • IdentityCoreConstants (23-176)
components/application-mgt/org.wso2.carbon.identity.application.mgt/src/test/java/org/wso2/carbon/identity/application/mgt/ApplicationManagementServiceImplTest.java (1)
components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityUtil.java (1)
  • IdentityUtil (131-2402)
components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java (2)
components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityUtil.java (1)
  • IdentityUtil (131-2402)
components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java (1)
  • IdPManagementConstants (28-753)
components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/util/FilterQueriesUtil.java (2)
components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityUtil.java (1)
  • IdentityUtil (131-2402)
components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/constant/APIResourceManagementConstants.java (1)
  • APIResourceManagementConstants (28-237)
🔇 Additional comments (11)
features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/org.wso2.carbon.identity.core.server.feature.default.json (1)

2187-2188: LGTM: Configuration for wildcard escaping added correctly.

The new configuration key api.filters.single_character_wildcard with an empty string default is appropriate. This allows underscore characters to be escaped in SQL LIKE queries by default, while providing flexibility to configure a custom single-character wildcard if needed.

components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/util/IdentityCoreConstants.java (2)

2-4: LGTM: License header updated.

Standard copyright and organization information update with no functional impact.


39-40: Verify configuration key naming convention for SINGLE_CHARACTER_WILDCARD constant.

The constant SINGLE_CHARACTER_WILDCARD = "APIFiltering.SingleCharacterWildcard" uses camelCase, but the code comment at line 2378 references api.filters.single_character_wildcard (snake_case). Confirm whether the constant value should match the configuration key format used in identity.xml and whether the comment reflects the intended configuration property name.

features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 (2)

4-18: License header year bump looks correct

Apache 2.0 header is intact and the year range update to 2019‑2025 is consistent with the rest of the codebase’s style.


5022-5025: APIFiltering block wiring looks good; verify default and docs

The new <APIFiltering> section and {{api.filters.single_character_wildcard}} binding follow existing template patterns and placement near other API-related flags makes sense. Please just confirm that:

  • api.filters.single_character_wildcard is always defined in the default config (and migration paths), and
  • The new [api.filters] single_character_wildcard option is documented with its default and semantics (literal vs wildcard behavior) so operators know how to use it.

If those are already covered, this fragment is good to go.

components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java (2)

2-16: Header year and organization update is fine

Copyright holder/year and license header formatting remain consistent with the rest of the codebase.


1004-1019: Wildcard escaping in appendFilterQuery looks correct; please verify across all DBs

  • Applying IdentityUtil.processSingleCharWildcard(value) for sw/ew/co before building the LIKE pattern centralizes single‑char wildcard handling (including underscore and backslash) and aligns this DAO with the new config‑driven behavior.
  • Adding ESCAPE '\\' to the LIKE fragments ensures that \_ (and escaped \) behave consistently as literals when a non‑underscore single‑character wildcard is configured.
  • Parameters are still bound via PreparedStatement (no interpolation of user values into SQL), so there’s no SQL‑injection risk introduced.

Please run or extend tests against all supported DBs (MySQL/MariaDB, H2, Oracle, MSSQL, PostgreSQL, DB2, Informix) to confirm that LIKE ... ESCAPE '\' behaves as expected in each dialect, especially when single_character_wildcard is customized away from _.

components/application-mgt/org.wso2.carbon.identity.application.mgt/src/main/java/org/wso2/carbon/identity/application/mgt/dao/impl/ApplicationDAOImpl.java (3)

2-2: Copyright year update is fine.

The year range extension to 2014–2025 is consistent with current changes; no functional impact.


3912-3927: Consistent use of ESCAPE '\' in simple app-name filters looks correct; verify across DBs.

Using "SP_APP.APP_NAME LIKE ? ESCAPE '\\'" in the blank/* and simple-name-with-asterisk paths aligns these cases with the more advanced filter handling and supports literal escaping of the configured single‑character wildcard. Since this feeds into vendor‑specific queries via String.format, and values are still bound as parameters, there is no added SQL injection risk.

Please confirm via tests that all supported DBs (MySQL/MariaDB/H2, Oracle, MSSQL, PostgreSQL, DB2, Informix) accept the ESCAPE '\' clause in these templates and behave the same as the existing attribute-based LIKE filters.


3970-3987: Adding ESCAPE '\' to attribute-based LIKE filters is aligned with the new wildcard model.

For non‑eq operations (sw, ew, co), switching to realSearchField + " LIKE ? ESCAPE '\\'" ensures that all LIKE clauses use the same escape semantics as the simple app-name filters and can rely on IdentityUtil.processSingleCharWildcard to prepare values.

Given this impacts OAuth client ID / SAML issuer filters as well, please verify that existing filters with configured single‑character wildcards and literal underscores still behave as expected after this change.

components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/util/FilterQueriesUtil.java (1)

126-131: LIKE wildcard preprocessing and ESCAPE usage look correct.

Limiting IdentityUtil.processSingleCharWildcard to SW/EW/CO before building the filter and appending ESCAPE '\' to all LIKE clauses is a clean way to centralize single‑char wildcard handling while keeping parameters bound safely via ?. The switch refactor to use static operator constants is also fine.

Also applies to: 143-157, 158-177, 205-227

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Underscore (_) is treated as a wildcard character in user searches on the Console app

1 participant