feat: implement role based access control rbac#42
Conversation
…sable component to use it on main page and while onboarding
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
There was a problem hiding this comment.
Pull request overview
Implements role-based access control (RBAC) end-to-end by introducing Keycloak-based authentication, backend role enforcement via Spring Security, and an admin UI (panel + protected routes) in the React client.
Changes:
- Add Keycloak auth bootstrap +
AuthProvider, and protect app/admin routes based on authentication + DB-backed role. - Add admin UI surface area (Admin Panel + Moderation/Import/Roles/Export pages) and supporting client APIs.
- Enforce admin-only backend endpoints and add admin competency bulk-import endpoints + allowed email-domain gating.
Reviewed changes
Copilot reviewed 42 out of 43 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/pages/SessionPage.tsx | Switch to /api/auth/me user lookup |
| src/pages/RolesPage.tsx | New roles management UI |
| src/pages/OnboardingPage.tsx | Integrate auth state + domain denial UX |
| src/pages/ModerationPage.tsx | New moderation UI w/ inline edits |
| src/pages/ImportPage.tsx | New admin import UI (JSON/CSV) |
| src/pages/HomePage.tsx | Start CTA now uses auth-aware navigation |
| src/pages/ExportPage.tsx | New export placeholder page |
| src/pages/DashboardPage.tsx | Load stats using authenticated userId |
| src/pages/AdminPage.tsx | New admin landing panel |
| src/lib/auth/keycloak.ts | Keycloak client config + init |
| src/lib/api/types.ts | Add degree + import result types |
| src/lib/api/session-helpers.ts | Add getCurrentUserAction() via /api/auth/me |
| src/lib/api/client.ts | Attach Keycloak bearer token via interceptor |
| src/lib/api/admin.ts | Add admin import API client |
| src/index.css | Expand exposed CSS variables |
| src/contexts/useAuth.ts | New useAuth() hook wrapper |
| src/contexts/AuthContext.tsx | New auth provider/state sync |
| src/contexts/auth-context.ts | Define auth context types |
| src/components/ProtectedRoute.tsx | Require auth + handle domain denial |
| src/components/navbar.tsx | Show sign-in/out + conditional Admin link |
| src/components/AdminRoute.tsx | Admin-only route guard |
| src/App.tsx | Wire AuthProvider + protected/admin routes |
| server/src/main/resources/db/migration/V9__update_users_for_keycloak_auth.sql | DB changes for Keycloak UUID subjects |
| server/src/main/resources/application.yml | Configure OAuth2 resource server + uploads + allowlist |
| server/src/main/java/de/tum/cit/memo/service/UserService.java | Find-or-create user by subject |
| server/src/main/java/de/tum/cit/memo/service/CompetencyService.java | Bulk competency import service |
| server/src/main/java/de/tum/cit/memo/security/SecurityConfig.java | Enforce RBAC + resource server JWT |
| server/src/main/java/de/tum/cit/memo/security/DbRoleJwtAuthenticationConverter.java | Load role from DB into authorities |
| server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java | Add existsByTitle |
| server/src/main/java/de/tum/cit/memo/MemoApiApplication.java | Enable configuration properties scan |
| server/src/main/java/de/tum/cit/memo/entity/User.java | Adjust user fields for Keycloak flow |
| server/src/main/java/de/tum/cit/memo/dto/ImportResult.java | Import result DTO |
| server/src/main/java/de/tum/cit/memo/dto/CompetencyImportRow.java | Import row DTO + validation |
| server/src/main/java/de/tum/cit/memo/controller/AuthController.java | /api/auth/me sync + domain allowlist |
| server/src/main/java/de/tum/cit/memo/controller/AdminController.java | Admin import endpoints (JSON/CSV/file) |
| server/src/main/java/de/tum/cit/memo/config/MemoProperties.java | Allowed email domains properties |
| server/docker/keycloak/memo-realm.json | Realm tweaks (email claim mapper, SMTP, etc.) |
| server/docker-compose.yml | Add Mailpit + Keycloak/server env updates |
| server/build.gradle | Add OAuth2 resource server dependency |
| public/silent-check-sso.html | Keycloak silent SSO support page |
| postcss.config.mjs | Remove redundant PostCSS config |
| auth-flow.svg | Document updated auth flow (diagram) |
| auth-flow.mmd | Document updated auth flow (source) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
🔍 Code Quality Report📊 Code Statistics🚨 Potential Issues✅ No console statements found |
Description
Implements role-based access control (RBAC) across the full stack. Introduces an
ADMINrole stored in the database, enforced on the backend via Spring Security, and surfaced in the frontend through protected routes and a dedicated Admin Panel with four sections: Moderation, Import, Roles, and Export.Type of Change
Related Issues
Changes Made
Client:
AdminRoutecomponent — redirects non-admins away from/admin/*/adminwith four sections: Moderation, Import, Roles, Exportrole === 'ADMIN'AuthContextfetches and stores the user's role from/api/auth/meon loginServer:
DbRoleJwtAuthenticationConverter— resolves the user's role from the database on every authenticated request and injects it into Spring Security contextSecurityConfig— admin-only endpoints protected withhasRole('ADMIN')AdminController— bulk competency import endpoints (JSON and CSV)AuthController— fast-fail with 403 if email domain not in allowlistMemoProperties— configurable allowed email domainsDatabase:
V9__update_users_for_keycloak_auth.sql— extends user ID column to 36 chars for Keycloak UUIDs, addsrolecolumn defaulting toUSERTesting
Test Cases
Manual Testing
demo@memo.local(USER): no Admin link visible,/adminredirects to dashboard, admin API endpoints return 403admin@memo.local(ADMIN): Admin link visible in navbar, all four admin sections accessible, role toggle and inline edits persist to the database