Add optional no-auth mode for simplified local testing

This update introduces an AUTH_MODE configuration that allows developers
to easily test the application locally without requiring Entra ID setup.

Changes:
- Add AUTH_MODE environment variable (entra/none) to .env.example and config
- Update auth decorators to support both authentication modes
- Create role selection page for no-auth mode (admin/user choice)
- Modify auth routes to conditionally use MSAL only in Entra ID mode
- Update UserModel to support mock test users with string IDs
- Add visual indicator in navbar when running in no-auth mode

Benefits:
- Zero Azure AD configuration needed for local development
- Quick testing of role-based features (admin vs user)
- Existing Entra ID functionality remains unchanged
- Simple toggle via environment variable

To use no-auth mode, set AUTH_MODE=none in .env file.
For production, use AUTH_MODE=entra (default).
This commit is contained in:
2025-10-20 20:03:46 -04:00
parent 795068c015
commit 2b471ef09f
7 changed files with 245 additions and 12 deletions

View File

@@ -67,8 +67,22 @@ class UserModel:
return None
@staticmethod
def get_by_id(user_id: int) -> Optional[Dict]:
"""Get user by ID"""
def get_by_id(user_id) -> Optional[Dict]:
"""Get user by ID (supports both integer IDs and string test IDs for no-auth mode)"""
# Handle test user IDs for no-auth mode
if isinstance(user_id, str) and user_id.startswith('test-'):
# Mock test user
role = 'admin' if 'admin' in user_id else 'user'
return {
'id': user_id,
'email': f'{role}@test.local',
'azure_oid': None,
'name': f'Test {role.capitalize()}',
'role': role,
'created_at': None,
'updated_at': None
}
with get_db() as conn:
cursor = conn.cursor()
cursor.execute(
@@ -211,13 +225,17 @@ class UserModel:
return [row[0] for row in cursor.fetchall()]
@staticmethod
def has_access_to_tenant(user_id: int, tenant_id: str) -> bool:
def has_access_to_tenant(user_id, tenant_id: str) -> bool:
"""Check if user has access to a specific tenant"""
# Admin has access to everything
user = UserModel.get_by_id(user_id)
if user and user['role'] == UserModel.ROLE_ADMIN:
return True
# Test users in no-auth mode don't have tenant associations
if isinstance(user_id, str) and user_id.startswith('test-'):
return False
# Check if user owns the tenant
with get_db() as conn:
cursor = conn.cursor()
@@ -228,7 +246,7 @@ class UserModel:
return cursor.fetchone() is not None
@staticmethod
def is_admin(user_id: int) -> bool:
def is_admin(user_id) -> bool:
"""Check if user has admin role"""
user = UserModel.get_by_id(user_id)
return user and user['role'] == UserModel.ROLE_ADMIN