diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 69a14b28..53bc804f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -32,6 +32,38 @@ jobs:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-maven-
+ - name: Configure echo mirror for dependency resolution
+ run: |
+ mkdir -p ~/.m2
+ cat > ~/.m2/settings.xml << EOF
+
+
+
+
+ echo-repo
+ *
+ https://maven.echohq.com
+
+
+
+
+ echo-repo
+
+ ${ECHO_LIBRARIES_ACCESS_KEY}
+
+
+
+ EOF
+ env:
+ ECHO_LIBRARIES_ACCESS_KEY: ${{ secrets.ECHO_LIBRARIES_ACCESS_KEY }}
+ - &install-pinned-maven
+ name: Install pinned Maven
+ run: |
+ MAVEN_VERSION=3.9.16 # Resolved through the echo mirror configured in ~/.m2/settings.xml
+ # Run outside the repo: the root pom loads the Tycho extension, which fails on the runner's Maven
+ (cd "${RUNNER_TEMP}" && mvn -B -q dependency:copy -Dartifact=org.apache.maven:apache-maven:${MAVEN_VERSION}:tar.gz:bin -DoutputDirectory=/tmp/maven-dist)
+ sudo tar -xzf /tmp/maven-dist/apache-maven-${MAVEN_VERSION}-bin.tar.gz -C /opt
+ echo "/opt/apache-maven-${MAVEN_VERSION}/bin" >> "$GITHUB_PATH"
- name: Run UI Tests
env:
CX_BASE_URI: ${{ secrets.CX_BASE_URI }}
@@ -71,6 +103,31 @@ jobs:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-maven-
+ - name: Configure echo mirror for dependency resolution
+ run: |
+ mkdir -p ~/.m2
+ cat > ~/.m2/settings.xml << EOF
+
+
+
+
+ echo-repo
+ *
+ https://maven.echohq.com
+
+
+
+
+ echo-repo
+
+ ${ECHO_LIBRARIES_ACCESS_KEY}
+
+
+
+ EOF
+ env:
+ ECHO_LIBRARIES_ACCESS_KEY: ${{ secrets.ECHO_LIBRARIES_ACCESS_KEY }}
+ - *install-pinned-maven
- name: Run Integration Tests
env:
CX_BASE_URI: ${{ secrets.CX_BASE_URI }}
@@ -110,6 +167,31 @@ jobs:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-maven-
+ - name: Configure echo mirror for dependency resolution
+ run: |
+ mkdir -p ~/.m2
+ cat > ~/.m2/settings.xml << EOF
+
+
+
+
+ echo-repo
+ *
+ https://maven.echohq.com
+
+
+
+
+ echo-repo
+
+ ${ECHO_LIBRARIES_ACCESS_KEY}
+
+
+
+ EOF
+ env:
+ ECHO_LIBRARIES_ACCESS_KEY: ${{ secrets.ECHO_LIBRARIES_ACCESS_KEY }}
+ - *install-pinned-maven
- name: Run Unit Tests with Coverage
env:
CX_BASE_URI: ${{ secrets.CX_BASE_URI }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 958a0e3a..bcb6a440 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -108,6 +108,39 @@ jobs:
restore-keys: |
${{ runner.os }}-maven-
+ - name: Configure echo mirror for dependency resolution
+ run: |
+ mkdir -p ~/.m2
+ cat > ~/.m2/settings.xml << EOF
+
+
+
+
+ echo-repo
+ *
+ https://maven.echohq.com
+
+
+
+
+ echo-repo
+
+ ${ECHO_LIBRARIES_ACCESS_KEY}
+
+
+
+ EOF
+ env:
+ ECHO_LIBRARIES_ACCESS_KEY: ${{ secrets.ECHO_LIBRARIES_ACCESS_KEY }}
+
+ - name: Install pinned Maven
+ run: |
+ MAVEN_VERSION=3.9.16 # Resolved through the echo mirror configured in ~/.m2/settings.xml
+ # Run outside the repo: the root pom loads the Tycho extension, which fails on the runner's Maven
+ (cd "${RUNNER_TEMP}" && mvn -B -q dependency:copy -Dartifact=org.apache.maven:apache-maven:${MAVEN_VERSION}:tar.gz:bin -DoutputDirectory=/tmp/maven-dist)
+ sudo tar -xzf /tmp/maven-dist/apache-maven-${MAVEN_VERSION}-bin.tar.gz -C /opt
+ echo "/opt/apache-maven-${MAVEN_VERSION}/bin" >> "$GITHUB_PATH"
+
- name: Update the POM version
env:
VERSION: ${{ inputs.tag }}
diff --git a/Cloud.md b/Claude.md
similarity index 95%
rename from Cloud.md
rename to Claude.md
index 459c1fac..93e928be 100644
--- a/Cloud.md
+++ b/Claude.md
@@ -137,6 +137,14 @@ Import into Eclipse:
- `File → Import → Maven → Existing Maven Projects`
- Select the repo root — all four modules will be detected
+### Build Configuration
+
+All Maven dependencies and plugins are resolved through the **Echo HQ Maven Repository** (`https://maven.echohq.com`), which serves CVE-patched builds of open-source libraries.
+
+- In CI/CD, each workflow writes `~/.m2/settings.xml` with an `echo-repo` mirror (`mirrorOf *`) and server credentials taken from the `ECHO_LIBRARIES_ACCESS_KEY` secret, the same way as `ast-cli-java-wrapper`.
+- For local builds, add the same `echo-repo` mirror and server to your `~/.m2/settings.xml`, with an empty username and your access key as the password. Never commit the key.
+- Eclipse platform bundles still come from the p2 repositories declared in `pom.xml`, and the runtime JARs bundled in the `lib/` folders are committed to the repo. Echo does not affect either of them.
+
### Build from CLI
```bash
diff --git a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/enums/SeverityExtendedTest.java b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/enums/SeverityExtendedTest.java
index 3e1f0d67..1823826f 100644
--- a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/enums/SeverityExtendedTest.java
+++ b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/enums/SeverityExtendedTest.java
@@ -79,7 +79,7 @@ void testEnumOrdinal_correctSequence() {
@Test
void testValues_returnsAllConstants() {
Severity[] values = Severity.values();
- assertEquals(8, values.length);
+ assertEquals(6, values.length);
}
@Test
@@ -88,7 +88,6 @@ void testValues_containsAllExpected() {
boolean hasCritical = false;
boolean hasHigh = false;
boolean hasLow = false;
- boolean hasGroupBy = false;
for (Severity s : values) {
if (s == Severity.CRITICAL) hasCritical = true;
@@ -99,7 +98,6 @@ void testValues_containsAllExpected() {
assertTrue(hasCritical);
assertTrue(hasHigh);
assertTrue(hasLow);
- assertTrue(hasGroupBy);
}
@Test
diff --git a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/enums/SeverityTest.java b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/enums/SeverityTest.java
index 52126ba1..6fa8c3c7 100644
--- a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/enums/SeverityTest.java
+++ b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/enums/SeverityTest.java
@@ -47,6 +47,6 @@ void testGetSeverity_roundTrip_allValues() {
@Test
void testEnumValues_count() {
- assertEquals(8, Severity.values().length);
+ assertEquals(6, Severity.values().length);
}
}
diff --git a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/properties/PreferencesTest.java b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/properties/PreferencesTest.java
index 4c8c6d91..22f4968e 100644
--- a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/properties/PreferencesTest.java
+++ b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/properties/PreferencesTest.java
@@ -5,7 +5,6 @@
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.IPreferencesService;
-import org.eclipse.jface.preference.IPreferenceStore;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -13,28 +12,24 @@
import org.mockito.MockedStatic;
import org.mockito.MockitoAnnotations;
-import com.checkmarx.eclipse.Activator;
import com.checkmarx.eclipse.common.preferences.Preferences;
class PreferencesTest {
- @Mock
- private IPreferencesService mockPreferencesService;
-
- @Mock
- private IPreferenceStore mockPreferenceStore;
+ private static final String[] STORED_TEST_KEYS = { "testKey", "key1", "key2" };
@Mock
- private Activator mockActivator;
+ private IPreferencesService mockPreferencesService;
private MockedStatic platformMock;
- private MockedStatic activatorMock;
+ private IPreferencesService realPreferencesService;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
+ // Captured before Platform is mocked: reading values back through Preferences.STORE needs the real service
+ realPreferencesService = Platform.getPreferencesService();
platformMock = mockStatic(Platform.class);
- activatorMock = mockStatic(Activator.class);
}
@AfterEach
@@ -42,8 +37,8 @@ void tearDown() {
if (platformMock != null) {
platformMock.close();
}
- if (activatorMock != null) {
- activatorMock.close();
+ for (String key : STORED_TEST_KEYS) {
+ Preferences.STORE.setToDefault(key);
}
}
@@ -118,33 +113,19 @@ void testGetAdditionalOptions_returnNull_whenNotSet() {
@Test
void testStore_setsValueInPreferenceStore() {
- activatorMock.when(Activator::getDefault).thenReturn(mockActivator);
- when(mockActivator.getPreferenceStore()).thenReturn(mockPreferenceStore);
-
+ useRealPreferencesService();
Preferences.store("testKey", "testValue");
- verify(mockActivator).getPreferenceStore();
- verify(mockPreferenceStore).setValue("testKey", "testValue");
+ assertEquals("testValue", Preferences.STORE.getString("testKey"));
}
@Test
void testStore_withEmptyValue() {
- activatorMock.when(Activator::getDefault).thenReturn(mockActivator);
- when(mockActivator.getPreferenceStore()).thenReturn(mockPreferenceStore);
-
+ useRealPreferencesService();
+ Preferences.store("testKey", "value");
Preferences.store("testKey", "");
- verify(mockPreferenceStore).setValue("testKey", "");
- }
-
- @Test
- void testStore_withNullValue() {
- activatorMock.when(Activator::getDefault).thenReturn(mockActivator);
- when(mockActivator.getPreferenceStore()).thenReturn(mockPreferenceStore);
-
- Preferences.store("testKey", null);
-
- verify(mockPreferenceStore).setValue("testKey", null);
+ assertEquals("", Preferences.STORE.getString("testKey"));
}
@Test
@@ -179,13 +160,15 @@ void testGetPref_multipleCallsWithDifferentKeys() {
@Test
void testStore_multipleValuesSequentially() {
- activatorMock.when(Activator::getDefault).thenReturn(mockActivator);
- when(mockActivator.getPreferenceStore()).thenReturn(mockPreferenceStore);
-
+ useRealPreferencesService();
Preferences.store("key1", "value1");
Preferences.store("key2", "value2");
- verify(mockPreferenceStore).setValue("key1", "value1");
- verify(mockPreferenceStore).setValue("key2", "value2");
+ assertEquals("value1", Preferences.STORE.getString("key1"));
+ assertEquals("value2", Preferences.STORE.getString("key2"));
+ }
+
+ private void useRealPreferencesService() {
+ platformMock.when(Platform::getPreferencesService).thenReturn(realPreferencesService);
}
}
diff --git a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/views/DataProviderTest.java b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/views/DataProviderTest.java
index 4e3955e0..a6d85b03 100644
--- a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/views/DataProviderTest.java
+++ b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/views/DataProviderTest.java
@@ -43,6 +43,12 @@ void setUp() {
FilterState.resetFilters();
}
+ /** These tests call the real CLI, so they can only run when CX_APIKEY is provided (e.g. not on fork PRs). */
+ private static void assumeCredentialsConfigured() {
+ Assumptions.assumeTrue(Environment.API_KEY != null && !Environment.API_KEY.isBlank(),
+ "CX_APIKEY is not set; skipping test that needs a live Checkmarx server");
+ }
+
@Test
void testSingletonInstance() {
DataProvider instance1 = DataProvider.getInstance();
@@ -66,12 +72,14 @@ void testSetAndGetCurrentResults() {
@Test
void testGetProjectsReturnsList() throws Exception {
+ assumeCredentialsConfigured();
List projects = dataProvider.getProjects();
assertNotNull(projects);
}
@Test
void testGetProjectsByNameReturnsList() throws Exception {
+ assumeCredentialsConfigured();
List projects = dataProvider.getProjects(TEST_PROJECT);
assertNotNull(projects);
}
diff --git a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/views/actions/ToolBarActionsTest.java b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/views/actions/ToolBarActionsTest.java
index af8d8612..42b1a83d 100644
--- a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/views/actions/ToolBarActionsTest.java
+++ b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/views/actions/ToolBarActionsTest.java
@@ -23,7 +23,9 @@
import org.mockito.Mockito;
import com.checkmarx.eclipse.enums.ActionName;
+import com.checkmarx.eclipse.enums.GroupingMode;
import com.checkmarx.eclipse.views.DataProvider;
+import com.checkmarx.eclipse.views.GlobalSettings;
import com.checkmarx.eclipse.enums.PluginListenerType;
import com.checkmarx.eclipse.common.enums.Severity;
@@ -137,6 +139,9 @@ void testRefreshToolbarRecreatesActions() {
void testGroupBySeverityAction() {
// createGroupByActions() runs inside a background Job so we test the toggle directly.
FilterState.groupBySeverity = false;
+ try (MockedStatic gs = Mockito.mockStatic(GlobalSettings.class)) {
+ FilterState.setGroupingMode(GroupingMode.SEVERITY);
+ }
assertTrue(FilterState.groupBySeverity);
}
diff --git a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/views/filters/FilterStateExtendedTest.java b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/views/filters/FilterStateExtendedTest.java
index 089d188b..4fd26a37 100644
--- a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/views/filters/FilterStateExtendedTest.java
+++ b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/views/filters/FilterStateExtendedTest.java
@@ -9,6 +9,7 @@
import org.mockito.MockitoAnnotations;
import com.checkmarx.eclipse.common.enums.Severity;
+import com.checkmarx.eclipse.enums.GroupingMode;
import com.checkmarx.eclipse.enums.State;
import com.checkmarx.eclipse.views.GlobalSettings;
import com.checkmarx.eclipse.views.filters.FilterState;
@@ -87,6 +88,7 @@ void testSetState_groupBySeverityToggle() {
boolean beforeState = FilterState.groupBySeverity;
try (MockedStatic mockSettings = mockStatic(GlobalSettings.class)) {
+ FilterState.setGroupingMode(GroupingMode.SEVERITY);
assertNotEquals(beforeState, FilterState.groupBySeverity);
}
}
diff --git a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/views/filters/FilterStateTest.java b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/views/filters/FilterStateTest.java
index ad5da5c0..8da6c6a6 100644
--- a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/views/filters/FilterStateTest.java
+++ b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/unit/views/filters/FilterStateTest.java
@@ -13,6 +13,7 @@
import org.mockito.Mockito;
import com.checkmarx.eclipse.common.enums.Severity;
+import com.checkmarx.eclipse.enums.GroupingMode;
import com.checkmarx.eclipse.enums.State;
import com.checkmarx.eclipse.views.GlobalSettings;
import com.checkmarx.eclipse.views.filters.FilterState;
@@ -136,6 +137,7 @@ void testSetState_info_togglesFromFalse() {
void testSetState_groupBySeverity_toggles() {
FilterState.groupBySeverity = true;
try (MockedStatic gs = Mockito.mockStatic(GlobalSettings.class)) {
+ FilterState.setGroupingMode(GroupingMode.SEVERITY);
}
assertFalse(FilterState.groupBySeverity);
}
@@ -144,6 +146,7 @@ void testSetState_groupBySeverity_toggles() {
void testSetState_groupByQueryName_toggles() {
FilterState.groupByQueryName = false;
try (MockedStatic gs = Mockito.mockStatic(GlobalSettings.class)) {
+ FilterState.setGroupingMode(GroupingMode.QUERY_NAME);
}
assertTrue(FilterState.groupByQueryName);
}
@@ -152,6 +155,7 @@ void testSetState_groupByQueryName_toggles() {
void testSetState_groupByStateName_toggles() {
FilterState.groupByStateName = false;
try (MockedStatic gs = Mockito.mockStatic(GlobalSettings.class)) {
+ FilterState.setGroupingMode(GroupingMode.STATE_NAME);
}
assertTrue(FilterState.groupByStateName);
}
diff --git a/checkmarx-ast-eclipse-plugin/.classpath b/checkmarx-ast-eclipse-plugin/.classpath
index 56a85caa..7ec84876 100644
--- a/checkmarx-ast-eclipse-plugin/.classpath
+++ b/checkmarx-ast-eclipse-plugin/.classpath
@@ -15,8 +15,8 @@
-
-
+
+
diff --git a/common-lib/.classpath b/common-lib/.classpath
index 082d5a03..aa6f37ef 100644
--- a/common-lib/.classpath
+++ b/common-lib/.classpath
@@ -9,11 +9,11 @@
-
-
+
+
diff --git a/common-lib/META-INF/MANIFEST.MF b/common-lib/META-INF/MANIFEST.MF
index dd946b85..8c4e98a2 100644
--- a/common-lib/META-INF/MANIFEST.MF
+++ b/common-lib/META-INF/MANIFEST.MF
@@ -6,8 +6,8 @@ Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: Checkmarx
Bundle-ClassPath: .,
lib/ast-cli-java-wrapper-2.4.31.jar,
- lib/jackson-core-2.21.4.jar,
- lib/jackson-databind-2.21.5.jar,
+ lib/jackson-core-2.22.3.jar,
+ lib/jackson-databind-2.22.3.jar,
lib/jackson-annotations-2.21.jar,
lib/slf4j-api-2.0.17.jar,
lib/slf4j-simple-2.0.17.jar,
diff --git a/common-lib/build.properties b/common-lib/build.properties
index d53d55b3..b29facd3 100644
--- a/common-lib/build.properties
+++ b/common-lib/build.properties
@@ -1,8 +1,8 @@
output.. = bin/
bin.includes = META-INF/,\
lib/ast-cli-java-wrapper-2.4.31.jar,\
- lib/jackson-core-2.21.4.jar,\
- lib/jackson-databind-2.21.5.jar,\
+ lib/jackson-core-2.22.3.jar,\
+ lib/jackson-databind-2.22.3.jar,\
lib/jackson-annotations-2.21.jar,\
lib/slf4j-api-2.0.17.jar,\
lib/slf4j-simple-2.0.17.jar,\
diff --git a/common-lib/lib/jackson-core-2.21.4.jar b/common-lib/lib/jackson-core-2.21.4.jar
deleted file mode 100644
index d43b85b8..00000000
--- a/common-lib/lib/jackson-core-2.21.4.jar
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:4b40a06396f239f8de2da57419adde6e94e5edc18a2171d471ea05eeed4e5c2d
-size 594183
diff --git a/common-lib/lib/jackson-core-2.22.3.jar b/common-lib/lib/jackson-core-2.22.3.jar
new file mode 100644
index 00000000..a16678a6
--- /dev/null
+++ b/common-lib/lib/jackson-core-2.22.3.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8a501126a385b25841915d839508f8a66e2a0dbc8a6709d055ef3b3e852b094c
+size 594776
diff --git a/common-lib/lib/jackson-databind-2.21.5.jar b/common-lib/lib/jackson-databind-2.21.5.jar
deleted file mode 100644
index 188a54f7..00000000
--- a/common-lib/lib/jackson-databind-2.21.5.jar
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:507418c0fafd38b2b2cfb704521630da613a8e4cc8381195a6f418017883e2c0
-size 1705906
diff --git a/common-lib/lib/jackson-databind-2.22.3.jar b/common-lib/lib/jackson-databind-2.22.3.jar
new file mode 100644
index 00000000..6cad31e3
--- /dev/null
+++ b/common-lib/lib/jackson-databind-2.22.3.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:556db5439e206114346043f68d200497dc96a0bca62a360a81784092ebd0e0a9
+size 1709604
diff --git a/devassist-lib/.classpath b/devassist-lib/.classpath
index d011c85e..98c96848 100644
--- a/devassist-lib/.classpath
+++ b/devassist-lib/.classpath
@@ -5,8 +5,8 @@
-
-
+
+
diff --git a/devassist-lib/src/com/checkmarx/eclipse/devassist/configuration/McpSettingsInjector.java b/devassist-lib/src/com/checkmarx/eclipse/devassist/configuration/McpSettingsInjector.java
index 7b2dc6cc..e4698c09 100644
--- a/devassist-lib/src/com/checkmarx/eclipse/devassist/configuration/McpSettingsInjector.java
+++ b/devassist-lib/src/com/checkmarx/eclipse/devassist/configuration/McpSettingsInjector.java
@@ -6,6 +6,9 @@
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
@@ -59,6 +62,8 @@ public final class McpSettingsInjector {
/** Bundle symbolic name of GitHub Copilot for Eclipse's UI plugin. */
private static final String COPILOT_UI_BUNDLE_ID = "com.microsoft.copilot.eclipse.ui";
+ private static final Set DEV_ENV_IAM_HOSTS = Set.of("iam-dev.dev.cxast.net");
+ private static final Pattern IAM_HOST_LABEL = Pattern.compile("(^|\\.)iam\\.");
/** Preference key Copilot reads its MCP server JSON from (Constants.MCP). */
private static final String MCP_PREFERENCE_KEY = "mcp";
@@ -304,23 +309,29 @@ private static String deriveBaseUrlFromIssuer(String issuer) {
CxLogger.info(LOG_TAG + " Issuer is null/empty, using fallback base URL");
return FALLBACK_BASE;
}
-
+
try {
CxLogger.info(LOG_TAG + " Deriving base URL from issuer: " + issuer);
String host = URI.create(issuer).getHost();
-
- if (host != null && host.contains("iam.checkmarx")) {
- String newHost = host.replace("iam", "ast");
- String baseUrl = "https://" + newHost;
- CxLogger.info(LOG_TAG + "Derived base URL: " + baseUrl);
- return baseUrl;
+
+ if (host == null || host.isBlank()) {
+ CxLogger.info(LOG_TAG + " Issuer has no host, using fallback");
+ return FALLBACK_BASE;
+ }
+
+
+ if (DEV_ENV_IAM_HOSTS.contains(host)) {
+ CxLogger.info(LOG_TAG + " Issuer host '" + host + "' is a dev env, using fallback base URL");
+ return FALLBACK_BASE;
}
-
- CxLogger.info(LOG_TAG + " Host does not match iam.checkmarx pattern, using fallback");
- return FALLBACK_BASE;
+
+ // Multi-tenant: swap only the "iam" host label (e.g. eu.iam.checkmarx.net -> eu.ast.checkmarx.net).
+ // Single-tenant: the issuer host is the tenant base URL.
+ Matcher iamLabel = IAM_HOST_LABEL.matcher(host);
+ return "https://" + (iamLabel.find() ? iamLabel.replaceFirst("$1ast.") : host);
} catch (Exception e) {
CxLogger.warning(LOG_TAG + " Failed to derive base URL from issuer: " + e.getMessage());
return FALLBACK_BASE;
}
}
-}
+ }