vault backup: 2026-05-07 10:38:27

This commit is contained in:
Vadym Samoilenko 2026-05-07 10:38:27 +01:00
parent 2f7f73be3a
commit 9ec7d3e155
3 changed files with 107 additions and 0 deletions

View file

@ -177,6 +177,10 @@ All endpoints except `/auth/login` require valid JWT in `Authorization: Bearer {
- **Recent fixes:** Accurate time tracking with interval union (no double-counting), project metadata fields, auto-detect repo URL from git remote, chart null-safety, async safety (selectinload, execute delete)
## Sessions
### 2026-05-07 Set up SSO with user isolation,
**Asked:** Set up SSO with user isolation, disable personal login, and map vadymsamoilenko@oliver.agecny to VadymSamoilenko@oliver.agecny.
**Done:** Implemented Azure AD SSO authentication with JWKS token validation, disabled legacy login endpoints, added user isolation, and migrated user account mapping.
### 2026-05-06 Developer requested calendar view with project
**Asked:** Developer requested calendar view with project time tracking, Azure DevOps sync, and daily task planner for work planning hub.
**Done:** Implemented calendar display, cache control fixes, and Live Feed bug fixes; deployed to production server successfully.
@ -268,6 +272,7 @@ All endpoints except `/auth/login` require valid JWT in `Authorization: Bearer {
## Change Log
| Date | Requested | Changed | Files |
|------|-----------|---------|-------|
| 2026-05-07 | SSO setup with user isolation | sso.py, auth.py, models.py, routers/auth.py — JWKS validation, removed /login endpoint, added azure_oid field, user migration | src/sso.py, src/auth.py, src/models.py, src/routers/auth.py |
| 2026-05-06 | Projects toFixed error | Add null checks and fallback values, verify rendering | ProjectsView.js, CardContent.vue |
| 2026-05-06 | Fix undefined toFixed() | Add null check for toFixed() call, verify server deployment | ProjectsView-CZF7uexl.js, CardContent.vue |
| 2026-05-06 | Fix Projects TypeError | Add null check before toFixed call | ProjectsView-CZF7uexl.js, CardContent.vue |

10
99 Daily/2026-05-07.md Normal file
View file

@ -0,0 +1,10 @@
---
date: 2026-05-07
tags: [daily]
---
## Session Log
- 10:37 (5min) | `cc-dashboard`
- **Asked:** Set up SSO with user isolation, disable personal login, and map vadymsamoilenko@oliver.agecny to VadymSamoilenko@oliver.agecny.
- **Done:** Implemented Azure AD SSO authentication with JWKS token validation, disabled legacy login endpoints, added user isolation, and migrated user account mapping.

View file

@ -0,0 +1,92 @@
---
tags: [tech-patterns, auto-generated]
source: cc-dashboard
created: 2026-05-07
---
# Azure AD SSO Integration with User Isolation
## When to use
When migrating an existing application from local authentication to Azure AD Single Sign-On (SSO), requiring user account mapping between legacy and SSO identities, with complete isolation of local login mechanisms.
## Prerequisites
- Azure AD tenant with application registration
- Application registered as Single Page Application (SPA) in Azure portal
- JWKS (JSON Web Key Set) endpoint available from Azure AD
- Backend framework supporting JWT token validation (Python/FastAPI recommended)
- Existing user database schema with password_hash and unique identifier columns
## Steps
1. **Register SPA in Azure AD**
- Add your application URL (e.g., `https://optical-dev.oliver.solutions/cc-dashboard/`) as a Redirect URI in Azure portal
- Note the Client ID and JWKS endpoint URL
2. **Create SSO validation module** (`src/sso.py`)
- Implement JWKS token validation
- Cache public keys from Azure AD JWKS endpoint
- Validate token signature and claims (issuer, audience, expiration)
- Extract user identity from token (e.g., `preferred_username` claim)
3. **Update authentication router** (`src/routers/auth.py`)
- Create new `POST /api/auth/microsoft` endpoint that accepts Azure AD tokens
- Remove legacy endpoints: `/login`, `/change-password`, `/register`
- Implement token validation and user lookup/creation in endpoint
4. **Modify user model** (`src/models.py`)
- Add `azure_oid` column (nullable, unique) to store Azure AD object ID
- Make `password_hash` nullable to allow SSO-only users
- Add migration to alter existing schema
5. **Map existing users to SSO identities**
- For each legacy user requiring SSO access, update `azure_oid` with their Azure AD object ID
- Example: map `vadymsamoilenko@oliver.agency``VadymSamoilenko@oliver.agecny` by setting matching `azure_oid`
6. **Implement development bypass** (`src/auth.py`)
- Add `DEV_AUTH_BYPASS` flag for local development
- Auto-login with test user when SSO is unavailable locally
- Disable this in production environments
7. **Remove password-based authentication**
- Disable local login endpoints completely
- Prevent password reset/change operations
- Ensure all user creation routes require SSO validation
## Key Configuration
```python
# .env or config
AZURE_AD_JWKS_URL=https://login.microsoftonline.com/{tenant}/discovery/v2.0/keys
AZURE_AD_CLIENT_ID=your-client-id
AZURE_AD_TENANT=your-tenant-id
DEV_AUTH_BYPASS=false # Set to true locally only
```
```python
# src/sso.py - Example validation
import jwt
from functools import lru_cache
@lru_cache(maxsize=1)
def get_jwks():
# Fetch and cache Azure AD public keys
pass
def validate_token(token: str):
# Validate signature using JWKS
# Check issuer, audience, expiration
# Return claims
pass
```
## Gotchas
- **User mapping case sensitivity**: Azure AD usernames may differ in casing from legacy usernames. Implement case-insensitive lookup or explicit mapping table.
- **Token expiration handling**: Azure AD tokens expire quickly. Implement token refresh logic on the frontend; don't rely on long-lived tokens.
- **JWKS caching**: Public keys rotate periodically. Implement cache invalidation or short TTL; don't cache indefinitely.
- **Nullable password fields**: Ensure password validation logic handles null values gracefully; add database constraint to prevent password-less local login attempts.
- **Development environment**: DEV_AUTH_BYPASS must be explicitly disabled in production; verify this during deployment checks.
- **Redirect URI matching**: Azure portal requires exact URL match (protocol, domain, path). Test with full deployment URL before going live.
## Source
Project: cc-dashboard