refactor: added check for unmanaged attribute#1611
Conversation
Signed-off-by: Tipu_Singh <tipu.singh@ayanworks.com>
📝 WalkthroughWalkthroughThis 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. ChangesUnmanaged Attribute Validation & Keycloak Integration
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~30 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
@coderabbitai Please review |
|
Tip For best results, initiate chat on the files or code changes.
[review] |
There was a problem hiding this comment.
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
📒 Files selected for processing (4)
apps/ecosystem/src/ecosystem.module.tsapps/ecosystem/src/ecosystem.service.tslibs/common/src/response-messages/index.tslibs/keycloak-config/src/keycloak-config.service.ts
Signed-off-by: Tipu_Singh <tipu.singh@ayanworks.com>
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
apps/ecosystem/src/ecosystem.service.ts (2)
1003-1003: 💤 Low valueUse optional chaining for the policy check.
SonarCloud flagged this conditional. Optional chaining reads more cleanly and removes the need for the explicit
!profileConfigshort-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 winMerge the duplicate
@credebl/commonimport.
CommonServiceis imported here whileErrorHandleris 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
📒 Files selected for processing (2)
apps/ecosystem/src/ecosystem.service.tslibs/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
| 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); | ||
| } | ||
| } |
There was a problem hiding this comment.
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.
🤖 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.



Summary by CodeRabbit
New Features
Bug Fixes
Chores