fix(keycloak): update user club attributes with real database UUIDs
- Replaced placeholder UUIDs (club-1-uuid, club-2-uuid) with real database UUIDs - Updated all 5 test users via Keycloak database - Restarted Keycloak to clear caches and apply changes Impact: - JWT tokens now contain real UUIDs in clubs claim - API endpoints accept X-Tenant-Id with real UUIDs (returns 200 OK) - Unblocks 46 remaining QA scenarios Documentation: - Created update-keycloak-club-uuids.py script for automation - Added KEYCLOAK_UPDATE_GUIDE.md with step-by-step instructions - Recorded learnings in notepad Ref: .sisyphus/evidence/final-f3-manual-qa.md lines 465-512
This commit is contained in:
@@ -2082,3 +2082,65 @@ bunx playwright test shifts.spec.ts --reporter=list
|
||||
- Add notification test (verify member receives email/notification on sign-up confirmation)
|
||||
|
||||
---
|
||||
|
||||
## Keycloak Club UUID Update (2026-03-05)
|
||||
|
||||
### Learnings
|
||||
|
||||
1. **Keycloak Admin API Limitations**
|
||||
- PUT /admin/realms/{realm}/users/{id} returns 204 No Content but may not persist attribute changes
|
||||
- Direct database updates are more reliable for user attributes
|
||||
- Always verify with database queries after API calls
|
||||
|
||||
2. **Keycloak User Attributes**
|
||||
- Stored in PostgreSQL `user_attribute` table (key-value pairs)
|
||||
- User list endpoint (/users) includes attributes in response
|
||||
- Single user endpoint (/users/{id}) may not include attributes in some configurations
|
||||
- Attributes are JSON strings stored in VARCHAR fields
|
||||
|
||||
3. **Token Attribute Mapping**
|
||||
- oidc-usermodel-attribute-mapper reads user attributes and includes in JWT
|
||||
- Configuration: `user.attribute: clubs` → `claim.name: clubs` → `jsonType.label: JSON`
|
||||
- Keycloak caches user data in memory after startup
|
||||
- Restart required after database updates for token changes to take effect
|
||||
|
||||
4. **UUID Update Strategy**
|
||||
- Map placeholder UUIDs to real database UUIDs
|
||||
- Execute updates at database level for reliability
|
||||
- Restart Keycloak to clear caches
|
||||
- Verify via JWT token decoding (base64 decode part 2 of token)
|
||||
- Test with API endpoints to confirm end-to-end flow
|
||||
|
||||
5. **Best Practices**
|
||||
- Always verify updates in database before restarting services
|
||||
- Document user-to-UUID mappings for future reference
|
||||
- Create automated scripts for reproducibility
|
||||
- Test both JWT tokens and API endpoints after updates
|
||||
|
||||
### Commands Proven Effective
|
||||
|
||||
**Update Database:**
|
||||
```bash
|
||||
docker exec workclub_postgres psql -U postgres -d keycloak << 'SQL'
|
||||
UPDATE user_attribute SET value = '{json}' WHERE user_id = 'uuid' AND name = 'clubs';
|
||||
SQL
|
||||
```
|
||||
|
||||
**Restart Keycloak:**
|
||||
```bash
|
||||
docker restart workclub_keycloak && sleep 10
|
||||
```
|
||||
|
||||
**Verify JWT:**
|
||||
```bash
|
||||
TOKEN=$(curl -s -X POST http://localhost:8080/realms/workclub/protocol/openid-connect/token \
|
||||
-d "client_id=workclub-app" -d "grant_type=password" -d "username=user" -d "password=pass" | jq -r '.access_token')
|
||||
echo $TOKEN | cut -d'.' -f2 | base64 -d | jq '.clubs'
|
||||
```
|
||||
|
||||
### Resolved Blocker
|
||||
|
||||
**Blocker #2 (Critical)**: JWT clubs claim uses placeholders instead of real UUIDs
|
||||
- Status: ✅ RESOLVED
|
||||
- Impact: Unblocks 46 remaining QA scenarios
|
||||
- Date: 2026-03-05
|
||||
|
||||
Reference in New Issue
Block a user