fix: keycloak migration advisory locks - #357
Conversation
Changed Files
|
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughCasbin policy import logic was changed to perform idempotent upserts keyed on subject, scope, organisation, and application, replacing removed/mismatched rules rather than relying on add-policy return counts. Keycloak-to-Casbin migration now acquires a per-realm advisory lock and paginates user and group fetches; a new advisory lock namespace variant was added. ChangesAuthz Import and Migration Hardening
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Migration as import_keycloak_authz_to_casbin
participant Lock as AdvisoryLock
participant Keycloak
participant Casbin
Migration->>Lock: acquire lock (KeycloakToCasbinMigration, realm)
alt lock unavailable
Lock-->>Migration: not acquired
Migration-->>Migration: log and return early
else lock acquired
loop paginated users
Migration->>Keycloak: fetch users page (offset, KEYCLOAK_PAGE_SIZE)
loop paginated groups per user
Migration->>Keycloak: fetch groups page (offset, KEYCLOAK_PAGE_SIZE)
end
Migration->>Migration: map groups to PolicyEntry
end
Migration->>Casbin: import_policy_entries(policies)
Casbin->>Casbin: upsert each policy by key, remove+add if changed
end
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 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 |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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 `@airborne_server/src/provider/authz/casbin.rs`:
- Around line 187-191: The policy import path currently updates Casbin via
remove_policies_for_filter_in_guard and guard.add_policy, but it never refreshes
authz_memberships, so imported roles can stay stale. After each successful
upsert in this import flow, trigger the membership cache refresh used by this
provider, and make sure to release the enforcer guard before doing so to avoid
self-deadlock. Use the existing import/policy upsert logic in casbin.rs as the
place to hook this in.
- Around line 187-190: The policy replacement in import_policy_entries() is not
atomic because remove_policies_for_filter_in_guard() persists before
add_policy(), so a failed insert can delete the existing grant. Update this flow
so removal and insertion happen in one transactional/rollback-safe unit, using
import_policy_entries(), remove_policies_for_filter_in_guard(), and add_policy()
as the main touchpoints. Also make sure authz_memberships is updated in the same
import path, since the current Casbin-only change can leave membership-based
reads stale after a successful import.
In `@airborne_server/src/provider/authz/migration.rs`:
- Around line 252-254: The error mapping in migration.rs currently includes the
user subject in the fetch failure message, which can leak PII into logs or API
responses. Update the `map_err` in the groups fetch path to return a generic
non-identifying message without interpolating `subject`, while keeping the error
context tied to the same fetch operation in `migration.rs`.
- Around line 179-190: The advisory lock handling in the migration flow is
unsafe because `AdvisoryLockGuard` only retains `DbPool`, so `release()`/`Drop`
may unlock through a different pooled session than the one that acquired the
lock. Update `AdvisoryLockGuard` and the `try_acquire_lock`/`release` path in
`migration.rs` to keep the checked-out connection (or use a transaction-scoped
advisory lock) bound to the same session for the full lifetime of the guard,
ensuring the lock is released on the original connection.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c61ba192-3b21-4ba5-8c34-89fae80d614d
📒 Files selected for processing (3)
airborne_server/src/provider/authz/casbin.rsairborne_server/src/provider/authz/migration.rsairborne_server/src/utils/advisory_lock.rs
f04000e to
45ff453
Compare
Summary by CodeRabbit
New Features
Bug Fixes