Skip to content

refactor: added check for unmanaged attribute#1611

Merged
tipusinghaw merged 2 commits into
mainfrom
feat/unmanaged-attribute-check
May 7, 2026
Merged

refactor: added check for unmanaged attribute#1611
tipusinghaw merged 2 commits into
mainfrom
feat/unmanaged-attribute-check

Conversation

@tipusinghaw

@tipusinghaw tipusinghaw commented May 6, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Runtime validation that unmanaged-attribute policy is enabled when turning on ecosystem features; Keycloak URL integration added to support checks.
  • Bug Fixes

    • New specific error messages for invalid ecosystem enablement and missing/unenabled unmanaged-attribute configuration.
  • Chores

    • Streamlined Keycloak ecosystem setup flow and reduced logging verbosity.

Signed-off-by: Tipu_Singh <tipu.singh@ayanworks.com>
@coderabbitai

coderabbitai Bot commented May 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds runtime unmanaged-attribute policy validation (Keycloak profile fetch) to EcosystemService, wires KeycloakUrlModule into the EcosystemModule, adds two response messages, and simplifies/silences parts of the Keycloak config mapper and scope-logging flow.

Changes

Unmanaged Attribute Validation & Keycloak Integration

Layer / File(s) Summary
Service: unmanaged-attribute validation and wiring
apps/ecosystem/src/ecosystem.service.ts
Adds CommonService and KeycloakUrlService imports and constructor injections; introduces checkUnmanagedAttributeEnabled() which fetches Keycloak user profile URL and profile via platform token and validates unmanagedAttributePolicy; called when enabling ecosystem in updateEcosystemConfig().
Module wiring
apps/ecosystem/src/ecosystem.module.ts
Imports KeycloakUrlModule and adds it to EcosystemModule imports array.
Error Message Definitions
libs/common/src/response-messages/index.ts
Adds invalidEcosystemEnabledFlag and unmanagedAttributeNotEnabled messages to ResponseMessages.ecosystem.error.
Keycloak Configuration Refactoring
libs/keycloak-config/src/keycloak-config.service.ts
Removes old Step 4 verification, adds/invokes per-client protocol mapper step, reduces scope and processing logs, simplifies existing-mapper early-return behavior, and streamlines mapper fetch logic.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant EcosystemService
  participant KeycloakUrlService
  participant CommonService
  participant Keycloak
  Client->>EcosystemService: request to enable ecosystem
  EcosystemService->>KeycloakUrlService: getUserProfileURL(realm)
  EcosystemService->>CommonService: httpGet(profileUrl, Authorization: Bearer token)
  CommonService->>Keycloak: GET profileUrl
  Keycloak-->>CommonService: profile config (unmanagedAttributePolicy)
  CommonService-->>EcosystemService: profile config
  EcosystemService-->>Client: success / throws BadRequest if not ENABLED
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Possibly related PRs

  • credebl/platform#1550: Updates ecosystem.service.ts with changes to the ecosystem enable/disable flow and related API logic.
  • credebl/platform#1565: Modifies the same ecosystem module and service files to integrate Keycloak modules and add runtime Keycloak attribute checks.
  • credebl/platform#1551: Modifies the same ecosystem module and service wiring with KeycloakUrlModule and related Keycloak integration.

Suggested reviewers

  • RinkalBhojani
  • pranalidhanavade

"I'm a rabbit who hops on code so fine,
I fetched the URL, then checked the line.
If Keycloak's set and tokens sing,
unmanaged attributes take to wing.
Hooray — the ecosystem's now in rhyme!" 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'refactor: added check for unmanaged attribute' directly describes the main change: adding validation logic for Keycloak unmanaged-attribute policy, which is evident across the modified files (ecosystem.service.ts, ecosystem.module.ts, response-messages, and keycloak-config.service.ts).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/unmanaged-attribute-check

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.

@tipusinghaw

Copy link
Copy Markdown
Contributor Author

@coderabbitai Please review

@coderabbitai

coderabbitai Bot commented May 6, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@tipusinghaw Sure! I'll start reviewing the PR now.

[review]

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/ecosystem/src/ecosystem.service.ts`:
- Around line 990-996: In checkUnmanagedAttributeEnabled validate that
process.env.KEYCLOAK_REALM (realmName) and the token returned by
this.clientRegistrationService.getPlatformManagementToken() are present and
non-empty before calling this.keycloakUrlService.GetUserProfileURL(...) or
this.commonService.httpGet(...); if realmName or token is missing, return early
or throw a clear error (with context) instead of proceeding, and consider
wrapping GetUserProfileURL/httpGet calls in a try/catch to surface actionable
errors (reference: KEYCLOAK_REALM, getPlatformManagementToken,
GetUserProfileURL, commonService.httpGet).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2f40cba7-981a-4bb9-95b0-6cd37f7d737f

📥 Commits

Reviewing files that changed from the base of the PR and between 1601616 and fa2d806.

📒 Files selected for processing (4)
  • apps/ecosystem/src/ecosystem.module.ts
  • apps/ecosystem/src/ecosystem.service.ts
  • libs/common/src/response-messages/index.ts
  • libs/keycloak-config/src/keycloak-config.service.ts

Comment thread apps/ecosystem/src/ecosystem.service.ts
Signed-off-by: Tipu_Singh <tipu.singh@ayanworks.com>
@tipusinghaw tipusinghaw self-assigned this May 7, 2026
@tipusinghaw tipusinghaw requested a review from RinkalBhojani May 7, 2026 06:45
@sonarqubecloud

sonarqubecloud Bot commented May 7, 2026

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
apps/ecosystem/src/ecosystem.service.ts (2)

1003-1003: 💤 Low value

Use optional chaining for the policy check.

SonarCloud flagged this conditional. Optional chaining reads more cleanly and removes the need for the explicit !profileConfig short-circuit:

♻️ Proposed fix
-    if (!profileConfig || UnmanagedAttributePolicy.ENABLED !== profileConfig.unmanagedAttributePolicy) {
+    if (profileConfig?.unmanagedAttributePolicy !== UnmanagedAttributePolicy.ENABLED) {
       throw new BadRequestException(ResponseMessages.ecosystem.error.unmanagedAttributeNotEnabled);
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/ecosystem/src/ecosystem.service.ts` at line 1003, The conditional
currently checks both for missing profileConfig and the unmanaged policy
explicitly; replace the explicit null check with optional chaining so the test
reads like "profileConfig?.unmanagedAttributePolicy !==
UnmanagedAttributePolicy.ENABLED" (locate the conditional using the symbols
profileConfig and UnmanagedAttributePolicy.ENABLED in ecosystem.service.ts) to
simplify the expression and avoid the explicit !profileConfig short-circuit.

18-18: ⚡ Quick win

Merge the duplicate @credebl/common import.

CommonService is imported here while ErrorHandler is imported from the same module on Line 56. SonarCloud flagged this. Consolidate to a single import statement.

♻️ Proposed fix
-import { CommonService } from '@credebl/common';
+import { CommonService, ErrorHandler } from '@credebl/common';
 import { KeycloakUrlService } from '@credebl/keycloak-url';
-import { ErrorHandler } from '@credebl/common';
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/ecosystem/src/ecosystem.service.ts` at line 18, The file has two
separate imports from '@credebl/common' (CommonService and ErrorHandler); merge
them into a single import statement importing both symbols from
'@credebl/common' (replace the separate import that declares CommonService and
the other import that declares ErrorHandler with one combined import listing
CommonService and ErrorHandler together).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/ecosystem/src/ecosystem.service.ts`:
- Around line 990-1006: The checkUnmanagedAttributeEnabled method currently
calls commonService.httpGet (using userProfileUrl) and lets transport/HTTP
errors bubble up, which gets masked by the subsequent BadRequestException when
profileConfig is falsy; wrap the await this.commonService.httpGet(...) call in a
try/catch inside checkUnmanagedAttributeEnabled, and on catch throw an
InternalServerErrorException that includes a clear message (e.g., Keycloak user
profile fetch failed or Keycloak unreachable) and the original error details;
also, if the call resolves but profileConfig is falsy, throw the same
InternalServerErrorException (instead of BadRequestException) so missing
profileConfig and transport failures produce a distinct, actionable server
error; refer to checkUnmanagedAttributeEnabled, commonService.httpGet,
userProfileUrl and profileConfig when making the change and preserve existing
ResponseMessages usage where appropriate.

---

Nitpick comments:
In `@apps/ecosystem/src/ecosystem.service.ts`:
- Line 1003: The conditional currently checks both for missing profileConfig and
the unmanaged policy explicitly; replace the explicit null check with optional
chaining so the test reads like "profileConfig?.unmanagedAttributePolicy !==
UnmanagedAttributePolicy.ENABLED" (locate the conditional using the symbols
profileConfig and UnmanagedAttributePolicy.ENABLED in ecosystem.service.ts) to
simplify the expression and avoid the explicit !profileConfig short-circuit.
- Line 18: The file has two separate imports from '@credebl/common'
(CommonService and ErrorHandler); merge them into a single import statement
importing both symbols from '@credebl/common' (replace the separate import that
declares CommonService and the other import that declares ErrorHandler with one
combined import listing CommonService and ErrorHandler together).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c0268462-8b3d-4143-84b4-6343d7833a02

📥 Commits

Reviewing files that changed from the base of the PR and between fa2d806 and 2809790.

📒 Files selected for processing (2)
  • apps/ecosystem/src/ecosystem.service.ts
  • libs/common/src/response-messages/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • libs/common/src/response-messages/index.ts

Comment on lines +990 to +1006
private async checkUnmanagedAttributeEnabled(): Promise<void> {
const realmName = process.env.KEYCLOAK_REALM;
const token = await this.clientRegistrationService.getPlatformManagementToken();

if (!realmName || !token) {
throw new InternalServerErrorException(ResponseMessages.ecosystem.error.keycloakRealmOrTokenMissing);
}

const userProfileUrl = await this.keycloakUrlService.GetUserProfileURL(realmName);
const profileConfig = await this.commonService.httpGet(userProfileUrl, {
headers: { authorization: `Bearer ${token}` }
});

if (!profileConfig || UnmanagedAttributePolicy.ENABLED !== profileConfig.unmanagedAttributePolicy) {
throw new BadRequestException(ResponseMessages.ecosystem.error.unmanagedAttributeNotEnabled);
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

httpGet failure path produces a misleading error.

If commonService.httpGet throws (Keycloak unreachable, 4xx/5xx, network timeout) the exception propagates as-is from this method, but if it resolves to a falsy profileConfig the user is told "unmanaged attribute not enabled" — which masks the real upstream failure and is actively confusing during ecosystem enablement.

Wrap the call so a transport/HTTP failure surfaces as a distinct, actionable error, and treat a missing profileConfig the same way:

🛡️ Suggested fix
-    const userProfileUrl = await this.keycloakUrlService.GetUserProfileURL(realmName);
-    const profileConfig = await this.commonService.httpGet(userProfileUrl, {
-      headers: { authorization: `Bearer ${token}` }
-    });
-
-    if (!profileConfig || UnmanagedAttributePolicy.ENABLED !== profileConfig.unmanagedAttributePolicy) {
-      throw new BadRequestException(ResponseMessages.ecosystem.error.unmanagedAttributeNotEnabled);
-    }
+    const userProfileUrl = await this.keycloakUrlService.GetUserProfileURL(realmName);
+    let profileConfig;
+    try {
+      profileConfig = await this.commonService.httpGet(userProfileUrl, {
+        headers: { authorization: `Bearer ${token}` }
+      });
+    } catch (error) {
+      this.logger.error(`Failed to fetch Keycloak user profile config: ${error?.message}`);
+      throw new InternalServerErrorException(
+        ResponseMessages.ecosystem.error.keycloakProfileFetchFailed
+      );
+    }
+
+    if (profileConfig?.unmanagedAttributePolicy !== UnmanagedAttributePolicy.ENABLED) {
+      throw new BadRequestException(ResponseMessages.ecosystem.error.unmanagedAttributeNotEnabled);
+    }
🧰 Tools
🪛 GitHub Check: SonarCloud Code Analysis

[warning] 1003-1003: Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZ39GcmbhwpNINSyU9hK&open=AZ39GcmbhwpNINSyU9hK&pullRequest=1611

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/ecosystem/src/ecosystem.service.ts` around lines 990 - 1006, The
checkUnmanagedAttributeEnabled method currently calls commonService.httpGet
(using userProfileUrl) and lets transport/HTTP errors bubble up, which gets
masked by the subsequent BadRequestException when profileConfig is falsy; wrap
the await this.commonService.httpGet(...) call in a try/catch inside
checkUnmanagedAttributeEnabled, and on catch throw an
InternalServerErrorException that includes a clear message (e.g., Keycloak user
profile fetch failed or Keycloak unreachable) and the original error details;
also, if the call resolves but profileConfig is falsy, throw the same
InternalServerErrorException (instead of BadRequestException) so missing
profileConfig and transport failures produce a distinct, actionable server
error; refer to checkUnmanagedAttributeEnabled, commonService.httpGet,
userProfileUrl and profileConfig when making the change and preserve existing
ResponseMessages usage where appropriate.

@tipusinghaw tipusinghaw merged commit da84943 into main May 7, 2026
8 checks passed
@tipusinghaw tipusinghaw deleted the feat/unmanaged-attribute-check branch May 7, 2026 08:53
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.

2 participants