AST-168518 Additional SCA Package Manager and Publish Plugin Version - #269
AST-168518 Additional SCA Package Manager and Publish Plugin Version#269cx-anand-nandeshwar wants to merge 13 commits into
Conversation
…chitectural cleanup This commit implements comprehensive refactoring to enable plugin version telemetry: Core changes: - Added agent name + plugin version stamping in CxWrapperFactory to report "Eclipse_<version>" in all API calls - Created common-lib/wrapper/CxWrapperFactory with version reading from OSGi Bundle metadata - Created WrapperProvider facade for common-lib (project/auth/tenant operations) - Created ScannerWrapperProvider in devassist-lib (scanner-specific operations, not exported) - Moved CxWrapperFactory from devassist-lib/factory to common-lib/wrapper (shared location) Refactoring across all wrapper consumers: - DataProvider: removed hand-built CxWrapper/CxConfig, uses WrapperProvider for all operations - Authenticator: centralized via WrapperProvider for test-connection credential validation - TenantSettingsProvider: uses WrapperProvider for MCP feature-flag checks - All 5 scanner services (Asca/OSS/Container/IaC/Secrets): inject ScannerWrapperProvider field Architectural improvements: - Eliminated duplicate wrapper-building logic across 9 files - Encapsulated scanner operations in devassist-lib (not exported from common-lib) - Established clear inversion-of-control pattern with injected provider instances - Added comprehensive unit tests (CxWrapperFactoryTest, WrapperProviderTest) Build & test verification: - Full reactor compile: SUCCESS - All 64 tests pass (58 DataProvider + 2 new factory tests + 4 new provider tests) - Java 17 JDT settings (consistent with Tycho build target) - Cleaned up dead comment blocks referencing deleted factory path Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Updated dependency version to match the latest stable release. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…g_mgr' into feature/anand_sca_plugin_version # Conflicts: # devassist-lib/src/com/checkmarx/eclipse/devassist/utils/DevAssistConstants.java
…n' into feature/anand_sca_plugin_version # Conflicts: # devassist-lib/src/com/checkmarx/eclipse/devassist/scanners/containers/ContainerScannerService.java # devassist-lib/src/com/checkmarx/eclipse/devassist/scanners/oss/OssScannerService.java
- Added plugin version with expected format - Resolved review comments for #265
Original alert (resolved)Security Policy Alert: Actions Policy ViolationThis workflow run has been blocked by StepSecurity's actions policy. Disallowed Actions:
To fix this issue, please modify the workflow to use only allowed actions. Contact your organization administrator to request changes to the allowed actions list if needed. For more information, see StepSecurity's Actions Policy documentation. |
Add a help page link, reposition the CLI help link and Connect/Logout buttons for correct layout ordering and spacing, and require a Yes/Cancel confirmation before logging out with a success message shown afterward.
Persist the connected state and success message across page reopens, lock/unlock the API key field and Connect/Logout buttons based on connection state, add a logout confirmation dialog, and focus the API key field on open.
Introduce Preferences.isAuthenticated() as the single source of truth for login state, and route every existing "API key non-blank" check through it instead, so a future auth method (e.g. OAuth) only needs to set/clear the same flag. Logout now only clears the validated flag and no longer wipes the stored API key, which stays visible/editable in the preferences page.
Security Policy Alert: Secret Policy ViolationThis workflow run has been blocked by StepSecurity's secrets policy because it accesses secrets and the workflow file differs from the default branch. Secret references detected:
To approve this workflow, please add the Note: The label must be added by someone other than the PR author (cx-anand-nandeshwar) or automation bots to ensure proper security review. After the label is added, you can re-run the blocked workflow to proceed. This workflow will be automatically approved once merged into the default branch. For more information, see StepSecurity's Secret Exfiltration Policy documentation. |
| @@ -97,30 +94,25 @@ public void setCurrentResults(Results currentResults) { | |||
| */ | |||
| public List<Project> getProjects() throws Exception { | |||
| List<Project> projectList = new ArrayList<Project>(); | |||
There was a problem hiding this comment.
Previously, authenticateWithAST() ran outside the try/catch, so a CxException propagated out of these methods; live callers in CheckmarxView.java (getProjects() ~line 2956, getTriageInfo() ~line 1984) both catch that exception and call PluginUtils.showMessage(...) to surface it. The refactor now catches IOException | InterruptedException | CxException inside DataProvider, logs it, and returns an empty list — so on auth failure, expired session, or network error, users now silently see an empty project/triage list instead of an error message. This is a normal-usage trigger (any auth/session hiccup), not an edge case.
Suggested fix: Let the checked exceptions propagate (remove the local catch, matching the pre-PR authenticateWithAST()-outside-try behavior), or explicitly re-throw after logging — as triageUpdate()/getScanInformation() already correctly do in this same file.
Evidence: New code: try { projectList = wrapperProvider.getProjects(LIMIT_FILTER); } catch (IOException | InterruptedException | CxException e) { CxLogger.error(...); } (no rethrow); CheckmarxView.java lines 2956-2968 and 1984-1996 both wrap the call in try/catch(Exception e) { ... showMessage(...) }, now unreachable for these exception types.
| // load() called on them yet at this point in createFieldEditors(), so their | ||
| // text | ||
| // controls are still empty. | ||
| lastValidatedApiKey = (Preferences.isCredentialsValidated() && StringUtils.isNotBlank(Preferences.getApiKey())) |
There was a problem hiding this comment.
Optional : lastValidatedApiKey persistence across page reopen, the logout confirmation dialog, and field enable/disable transitions are meaningfully complex new interacting logic with no test anywhere in the suite.
| connectionButton.setLayoutData(connectionButtonGridData); | ||
| // Disabled while already connected - re-enabled on logout (see logoutButton | ||
| // below). | ||
| connectionButton.setEnabled(!isConnected); |
There was a problem hiding this comment.
Connect button no longer disabled when the API key field is blank
Suggested Fix : Restore the blank-check in both the initial setEnabled call and the modify listener (!stillMatchesValidatedKey && StringUtils.isNotBlank(textControl.getText())), and/or add the same blank-guard Authenticator.doAuthentication is missing relative to TenantSettingsProvider.isAiMcpServerEnabled.
Evidence: PreferencesPage.java:266 connectionButton.setEnabled(!isConnected);; lines 280-293 modify listener never checks blankness; line ~426 logout handler re-enables Connect with a field just cleared to ""; TenantSettingsProvider.java:25 shows the blank-guard pattern Authenticator.java lacks.
| apiKey_str, additionalParams_str); | ||
| return Authenticator.INSTANCE.doAuthentication(apiKey_str, additionalParams_str); | ||
| } catch (Throwable t) { | ||
| CxLogger.error(PluginConstants.ERROR_AUTHENTICATING_AST, new Exception(t)); |
There was a problem hiding this comment.
CxLogger.error(PluginConstants.ERROR_AUTHENTICATING_AST, new Exception(t)); passes the raw %s-containing format string without String.format, dropping the actual failure cause from the log — operators only ever see the literal text with %s in it, right on the Connect-flow's exception path this PR reworked.
Suggested fix: CxLogger.error(String.format(PluginConstants.ERROR_AUTHENTICATING_AST, t.getMessage()), new Exception(t)); — matches the correct pattern already used in Authenticator.java:31.
Evidence: PreferencesPage.java:317 vs. Authenticator.java:31 (correct pattern in the same authentication flow).
| } | ||
|
|
||
| // for test only | ||
| public Authenticator(Logger logger) { |
There was a problem hiding this comment.
doAuthentication() now calls new WrapperProvider().authValidate(...), which builds its own logger internally in CxWrapperFactory — the injected log field is write-only, so the "for test only" constructor no longer isolates log output the way its comment implies.
Suggested fix: Remove the now-unused log field/constructor, or thread the injected logger through to WrapperProvider/CxWrapperFactory if test log-isolation is still a goal.
Evidence: Authenticator.java lines 10-20 (log field assigned, never read); line 27 delegates entirely to new WrapperProvider().authValidate(...).
| private Authenticator() { | ||
|
|
||
| public Authenticator() { |
There was a problem hiding this comment.
Constructor widened from private to public, weakening the singleton invariant
public static final Authenticator INSTANCE = new Authenticator(); implies single-instance usage, but the no-arg constructor is now public with no current caller needing it (repo-wide grep finds only INSTANCE's own initializer). No live regression today, but it invites accidental multi-instantiation if the class gains real per-instance state later.
Suggested fix: Revert to private Authenticator() unless a specific caller requires public construction.
Evidence: Diff: -private Authenticator() { / +public Authenticator() {; INSTANCE field retained unchanged.
| import com.checkmarx.eclipse.devassist.common.ScanResult; | ||
| import com.checkmarx.eclipse.devassist.common.ScannerConfig; | ||
| import com.checkmarx.eclipse.devassist.utils.DevAssistConstants; | ||
| import com.checkmarx.eclipse.devassist.utils.ScanEngine; |
There was a problem hiding this comment.
Two structurally different ScanEngine enums coexist in the repo; this file is the sole outlier using utils.ScanEngine instead of model.ScanEngine. Harmless today because the only use is .name() feeding a String field and both produce "ASCA", but since the types are distinct classes, passing this file's constant into any of the many APIs keyed on model.ScanEngine (ScannerStateManager, RemediationManager) would hit a confusing compile error, and a careless workaround could silently diverge ASCA's state/notification path from the rest of the engine-keyed logic.
Suggested fix: Change the import back to com.checkmarx.eclipse.devassist.model.ScanEngine; consider deleting the unused duplicate utils.ScanEngine enum entirely.
Evidence: Diff swaps model.ScanEngine → utils.ScanEngine; grep confirms 17 other files use model.ScanEngine exclusively; only usage here is .engineName(ScanEngine.ASCA.name()).
| scanResult = CxWrapperFactory.build().ScanAsca(path, ascaLatestVersion, agent, null); | ||
| scanResult = wrapperProvider.scanAsca(path, ascaLatestVersion, agent, null); | ||
| } catch (IOException e) { | ||
| e.printStackTrace(); |
There was a problem hiding this comment.
Scan failures logged via e.printStackTrace() instead of CxLogger, inconsistent with sibling scanners touched by this same PR
Suggested fix: Replace e.printStackTrace() with CxLogger.error(LOG_TAG + " scan failed: " + e.getMessage(), e) in all three files, matching the Oss/Secrets pattern.
| PYTHON(List.of("**/requirement*.txt", "**/constraints.txt", "**/constraints-*.txt", "**/pyproject.toml", | ||
| "**/setup.cfg", "**/setup.py")), | ||
| BOWER(List.of("**/bower.json")), | ||
| //YARN(List.of("package.json", "yarn.lock")), |
| GO("go", ManifestFilePattern.GO), | ||
| PYTHON("python", ManifestFilePattern.PYTHON), | ||
| BOWER("bower", ManifestFilePattern.BOWER), | ||
| //YARN("yarn", ManifestFilePattern.YARN), |
There was a problem hiding this comment.
PR-claimed Yarn support is not actually implemented — enum constant fully commented out
cx-atish-jadhav
left a comment
There was a problem hiding this comment.
Changes for SCA package manager validated all OK
By submitting a PR to this repository, you agree to the terms within the Checkmarx Code of Conduct. Please see the contributing guidelines for how to create and submit a high-quality PR for this repo.
Description
connection state.
References
Testing
Checklist