Skip to content

Sync realm roles from Keycloak in admin service#423

Open
iammajid wants to merge 4 commits intodevelopfrom
fix/admin-sync-realm-roles
Open

Sync realm roles from Keycloak in admin service#423
iammajid wants to merge 4 commits intodevelopfrom
fix/admin-sync-realm-roles

Conversation

@iammajid
Copy link
Copy Markdown
Contributor

  • Sync effective realm roles from Keycloak during user sync
  • Read back effective roles from Keycloak after role update instead of writing submitted roles directly to DB

@iammajid iammajid requested a review from SailReal March 16, 2026 10:14
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 16, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1667d250-0e35-40ab-a6ab-27b534173328

📥 Commits

Reviewing files that changed from the base of the PR and between 666d321 and 87375f4.

📒 Files selected for processing (1)
  • backend/src/main/java/org/cryptomator/hub/keycloak/KeycloakAdminService.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/src/main/java/org/cryptomator/hub/keycloak/KeycloakAdminService.java

Walkthrough

The change adds reading of effective realm roles from Keycloak into KeycloakAdminService. In syncUser, after populating user fields, the code now fetches effective realm roles via Keycloak, maps role names through RealmRole.fromKcNames, and stores their Keycloak names in dbUser.realmRoles. In updateUserRoles, after applying role mappings to Keycloak, the code now retrieves the effective roles from Keycloak, maps them, and updates dbUser.realmRoles. A RoleRepresentation import was added to support these reads.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Sync realm roles from Keycloak in admin service' accurately and directly describes the main change: synchronizing realm roles from Keycloak in the admin service.
Description check ✅ Passed The description clearly relates to the changeset, detailing the two main modifications: syncing effective realm roles during user sync and reading back roles after updates instead of writing submitted roles directly.

✏️ 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 fix/admin-sync-realm-roles

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
Copy Markdown
Member

@overheadhunter overheadhunter left a comment

Choose a reason for hiding this comment

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

We deliberately chose to first sync to db and then sync to KC.

This ensures consistency: If DB sync fails, no data will reach KC. If KC sync fails, the DB sync will be rolled back (due to the @Transactional method finishing exceptionally)

@iammajid iammajid requested a review from overheadhunter March 18, 2026 09:21
Copy link
Copy Markdown
Contributor

@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.

🧹 Nitpick comments (1)
backend/src/main/java/org/cryptomator/hub/keycloak/KeycloakAdminService.java (1)

208-211: Consider extracting the duplicated effective-role mapping into one helper.

Both blocks implement the same mapping pipeline; centralizing it reduces drift risk.

♻️ Suggested refactor
@@
-		var kcRoleNames = userResource.roles().realmLevel().listEffective().stream()
-				.map(RoleRepresentation::getName)
-				.toList();
-		dbUser.setRealmRoles(RealmRole.fromKcNames(kcRoleNames).stream().map(RealmRole::kcName).toArray(String[]::new));
+		dbUser.setRealmRoles(mapEffectiveRealmRoles(userResource.roles().realmLevel().listEffective()));
@@
-		var kcRoleNames = roleMappings.listEffective().stream()
-				.map(RoleRepresentation::getName)
-				.toList();
-		dbUser.setRealmRoles(RealmRole.fromKcNames(kcRoleNames).stream().map(RealmRole::kcName).toArray(String[]::new));
+		dbUser.setRealmRoles(mapEffectiveRealmRoles(roleMappings.listEffective()));
@@
+	private static String[] mapEffectiveRealmRoles(List<RoleRepresentation> effectiveRoles) {
+		var kcRoleNames = effectiveRoles.stream().map(RoleRepresentation::getName).toList();
+		return RealmRole.fromKcNames(kcRoleNames).stream().map(RealmRole::kcName).toArray(String[]::new);
+	}

Also applies to: 307-310

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/src/main/java/org/cryptomator/hub/keycloak/KeycloakAdminService.java`
around lines 208 - 211, Duplication: two identical pipelines transform Keycloak
effective role representations into String[] for dbUser; extract that logic into
a single private helper in KeycloakAdminService (e.g., a method like
extractRealmRoleNames(UserResource userResource) or
convertEffectiveKcRolesToRealmRoleNames) that calls
userResource.roles().realmLevel().listEffective(), maps
RoleRepresentation::getName, passes through
RealmRole.fromKcNames(...).stream().map(RealmRole::kcName).toArray(String[]::new)
and return the String[]; then replace both occurrences (the block using
kcRoleNames and the similar block at 307-310) to call the new helper and
setRealmRoles with its result.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@backend/src/main/java/org/cryptomator/hub/keycloak/KeycloakAdminService.java`:
- Around line 208-211: Duplication: two identical pipelines transform Keycloak
effective role representations into String[] for dbUser; extract that logic into
a single private helper in KeycloakAdminService (e.g., a method like
extractRealmRoleNames(UserResource userResource) or
convertEffectiveKcRolesToRealmRoleNames) that calls
userResource.roles().realmLevel().listEffective(), maps
RoleRepresentation::getName, passes through
RealmRole.fromKcNames(...).stream().map(RealmRole::kcName).toArray(String[]::new)
and return the String[]; then replace both occurrences (the block using
kcRoleNames and the similar block at 307-310) to call the new helper and
setRealmRoles with its result.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a214198b-a1b6-4747-ab7a-2c4808e96b06

📥 Commits

Reviewing files that changed from the base of the PR and between 0939e59 and 666d321.

📒 Files selected for processing (1)
  • backend/src/main/java/org/cryptomator/hub/keycloak/KeycloakAdminService.java

Copy link
Copy Markdown
Member

@overheadhunter overheadhunter left a comment

Choose a reason for hiding this comment

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

What are "effective roles"? Do they include roles inherited from groups?

If yes, should we really attach them to "users" in our db? Doesn't this produce inconsistencies? Or incorrectly sync back to kc users?

@iammajid iammajid requested a review from overheadhunter April 1, 2026 12:35
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