mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-05-07 13:00:22 -05:00
29f7186ee8
Complete reorganization of project documentation to improve discoverability, navigation, and maintainability. All documentation has been restructured into a clear, role-based hierarchy. ## Major Changes ### New Directory Structure - Created `docs/api/` for API documentation - Created `docs/admin/` with subdirectories: - `admin/configuration/` - Configuration guides - `admin/deployment/` - Deployment guides - `admin/security/` - Security documentation - `admin/monitoring/` - Monitoring and analytics - Created `docs/development/` for developer documentation - Created `docs/guides/` for user-facing guides - Created `docs/reports/` for analysis reports and summaries - Created `docs/changelog/` for detailed changelog entries (ready for future use) ### File Organization #### Moved from Root Directory (40+ files) - Implementation notes → `docs/implementation-notes/` - Test reports → `docs/testing/` - Analysis reports → `docs/reports/` - User guides → `docs/guides/` #### Reorganized within docs/ - API documentation → `docs/api/` - Administrator documentation → `docs/admin/` (with subdirectories) - Developer documentation → `docs/development/` - Security documentation → `docs/admin/security/` - Telemetry documentation → `docs/admin/monitoring/` ### Documentation Updates #### docs/README.md - Complete rewrite with improved navigation - Added visual documentation map - Organized by role (Users, Administrators, Developers) - Better categorization and quick links - Updated all internal links to new structure #### README.md (root) - Updated all documentation links to reflect new structure - Fixed 8 broken links #### app/templates/main/help.html - Enhanced "Where can I get additional help?" section - Added links to new documentation structure - Added documentation index link - Added admin documentation link for administrators - Improved footer with organized documentation links - Added "Complete Documentation" section with role-based links ### New Index Files - Created README.md files for all new directories: - `docs/api/README.md` - `docs/guides/README.md` - `docs/reports/README.md` - `docs/development/README.md` - `docs/admin/README.md` ### Cleanup - Removed empty `docs/security/` directory (moved to `admin/security/`) - Removed empty `docs/telemetry/` directory (moved to `admin/monitoring/`) - Root directory now only contains: README.md, CHANGELOG.md, LICENSE ## Results **Before:** - 45+ markdown files cluttering root directory - Documentation scattered across root and docs/ - Difficult to find relevant documentation - No clear organization structure **After:** - 3 files in root directory (README, CHANGELOG, LICENSE) - Clear directory structure organized by purpose and audience - Easy navigation with role-based organization - All documentation properly categorized - Improved discoverability ## Benefits 1. Better Organization - Documentation grouped by purpose and audience 2. Easier Navigation - Role-based sections (Users, Admins, Developers) 3. Improved Discoverability - Clear structure with README files in each directory 4. Cleaner Root - Only essential files at project root 5. Maintainability - Easier to add and organize new documentation ## Files Changed - 40+ files moved from root to appropriate docs/ subdirectories - 15+ files reorganized within docs/ - 3 major documentation files updated (docs/README.md, README.md, help.html) - 5 new README index files created - 2 empty directories removed All internal links have been updated to reflect the new structure.
203 lines
8.7 KiB
Markdown
203 lines
8.7 KiB
Markdown
## OpenID Connect (OIDC) Setup Guide
|
||
|
||
This guide explains how to enable Single Sign-On (SSO) with OpenID Connect for TimeTracker. OIDC is optional; you can run with local login only, OIDC only, or both.
|
||
|
||
### Quick Summary
|
||
|
||
- Set `AUTH_METHOD=oidc` (SSO only) or `AUTH_METHOD=both` (SSO + local password authentication).
|
||
- Configure `OIDC_ISSUER`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`, and `OIDC_REDIRECT_URI`.
|
||
- Optional: Configure admin mapping via `OIDC_ADMIN_GROUP` or `OIDC_ADMIN_EMAILS`.
|
||
- Restart the app. The login page will show an “Sign in with SSO” button when enabled.
|
||
|
||
### Prerequisites
|
||
|
||
- A running TimeTracker instance (Docker or local).
|
||
- An OIDC provider (e.g., Azure AD, Okta, Keycloak, Auth0, Google Workspace).
|
||
- A client application registered at your IdP with Authorization Code flow enabled.
|
||
|
||
### 1) Application URLs
|
||
|
||
You will need these URLs when creating the OIDC client at your Identity Provider:
|
||
|
||
- Authorization callback (Redirect URI):
|
||
- `https://<your-app-host>/auth/oidc/callback`
|
||
- Post-logout redirect (optional):
|
||
- `https://<your-app-host>/`
|
||
|
||
Make sure your external URL and protocol (HTTP/HTTPS) match how users access the app. Behind a reverse proxy, ensure the proxy sets `X-Forwarded-Proto` so redirects/cookies work correctly.
|
||
|
||
### 2) Required Environment Variables
|
||
|
||
Add these to your environment (e.g., `.env`, Docker Compose, or Kubernetes Secrets):
|
||
|
||
```
|
||
AUTH_METHOD=oidc # Options: none | local | oidc | both (see section 5 for details)
|
||
|
||
# Core OIDC settings
|
||
OIDC_ISSUER=https://idp.example.com/realms/your-realm
|
||
OIDC_CLIENT_ID=your-client-id
|
||
OIDC_CLIENT_SECRET=your-client-secret
|
||
OIDC_REDIRECT_URI=https://your-app.example.com/auth/oidc/callback
|
||
|
||
# Scopes and claims (defaults are usually fine)
|
||
OIDC_SCOPES=openid profile email
|
||
OIDC_USERNAME_CLAIM=preferred_username
|
||
OIDC_FULL_NAME_CLAIM=name
|
||
OIDC_EMAIL_CLAIM=email
|
||
OIDC_GROUPS_CLAIM=groups
|
||
|
||
# Optional admin mapping
|
||
OIDC_ADMIN_GROUP=timetracker-admins # If your IdP issues a groups claim
|
||
OIDC_ADMIN_EMAILS=alice@company.com,bob@company.com
|
||
|
||
# Optional: RP-Initiated Logout (set only if your provider supports end_session_endpoint)
|
||
# If unset, users will be logged out locally and redirected to TimeTracker's login page.
|
||
# If set, TimeTracker will redirect to the provider's logout endpoint after local logout.
|
||
OIDC_POST_LOGOUT_REDIRECT_URI=https://your-app.example.com/
|
||
```
|
||
|
||
Also ensure the standard app settings are configured (database, secret key, etc.). See `env.example` for a complete template.
|
||
|
||
### 3) Provider-Specific Notes
|
||
|
||
- Azure AD (Entra ID)
|
||
- Issuer: `https://login.microsoftonline.com/<tenant-id>/v2.0`
|
||
- Use `openid profile email` scopes.
|
||
- Preferred username commonly available via `preferred_username` or `upn`.
|
||
- Group claims may need to be enabled in App Registration → Token configuration.
|
||
|
||
- Okta
|
||
- Issuer: `https://<yourOktaDomain>/oauth2/default`
|
||
- Add claims for `groups` if you want role mapping by group.
|
||
|
||
- Keycloak
|
||
- Issuer: `https://<keycloak>/realms/<realm>`
|
||
- You can map custom claims and groups in the realm client.
|
||
|
||
- Google Workspace
|
||
- Issuer: `https://accounts.google.com`
|
||
- Groups generally not available by default; prefer admin mapping via emails.
|
||
|
||
### 4) Behavior and Mapping
|
||
|
||
- When a user completes SSO:
|
||
- We parse ID token and/or fetch userinfo to get `preferred_username`, `name`, `email` and optional `groups`.
|
||
- We upsert a local user record with `username`, `full_name`, `email`, and store OIDC linkage in `oidc_issuer` + `oidc_sub`.
|
||
- If `ALLOW_SELF_REGISTER=true` (default), unknown users are created on first login; otherwise they’re blocked.
|
||
- Admin role can be granted if user’s groups contains `OIDC_ADMIN_GROUP` or if user’s email is in `OIDC_ADMIN_EMAILS`.
|
||
|
||
### 5) Authentication Methods
|
||
|
||
The `AUTH_METHOD` environment variable controls how users authenticate with TimeTracker. It supports four options:
|
||
|
||
#### Available Options
|
||
|
||
1. **`none`** - No password authentication (username only)
|
||
- Users log in with just their username, no password required
|
||
- No password field shown on login page
|
||
- Useful for trusted internal networks or development environments
|
||
- Self-registration works (users can create accounts by entering any username)
|
||
- **Note:** This is the least secure option and should only be used in trusted environments
|
||
|
||
2. **`local`** - Password authentication required (default)
|
||
- Users must set and use a password to log in
|
||
- Password field is shown on login page
|
||
- Users without passwords are prompted to set one in their profile
|
||
- Passwords can be changed in user profile settings
|
||
- Self-registration works (new users must provide a password during registration)
|
||
- Works for both regular login and kiosk mode
|
||
- **Note:** This is the recommended option for most installations
|
||
|
||
3. **`oidc`** - OIDC/Single Sign-On only
|
||
- Users authenticate via your OIDC provider (e.g., Azure AD, Okta, Keycloak)
|
||
- Local login form is hidden
|
||
- `/login` redirects directly to OIDC login
|
||
- Requires OIDC configuration (see Required Environment Variables above)
|
||
- Self-registration still works if `ALLOW_SELF_REGISTER=true` (users created on first OIDC login)
|
||
|
||
4. **`both`** - OIDC + Local password authentication
|
||
- Shows both SSO button and local login form
|
||
- Users can choose to log in with OIDC or use username/password
|
||
- Local authentication requires passwords (same as `local` mode)
|
||
- Best for organizations transitioning to SSO or supporting mixed authentication
|
||
- Requires OIDC configuration to be set up
|
||
|
||
#### Summary Table
|
||
|
||
| Mode | Password Field | Password Required | OIDC Available | Self-Register | Use Case |
|
||
|------|---------------|-------------------|----------------|---------------|----------|
|
||
| `none` | ❌ No | ❌ No | ❌ No | ✅ Yes | Trusted internal networks, development |
|
||
| `local` | ✅ Yes | ✅ Yes | ❌ No | ✅ Yes | Standard password authentication |
|
||
| `oidc` | ❌ No | ❌ No | ✅ Yes | ✅ Yes | Enterprise SSO only |
|
||
| `both` | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | Mixed authentication (SSO + local) |
|
||
|
||
### 6) Docker Compose Example
|
||
|
||
```yaml
|
||
services:
|
||
app:
|
||
image: ghcr.io/your-org/timetracker:latest
|
||
environment:
|
||
- AUTH_METHOD=oidc
|
||
- OIDC_ISSUER=https://idp.example.com/realms/your-realm
|
||
- OIDC_CLIENT_ID=${OIDC_CLIENT_ID}
|
||
- OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET}
|
||
- OIDC_REDIRECT_URI=https://your-app.example.com/auth/oidc/callback
|
||
- OIDC_SCOPES=openid profile email
|
||
- OIDC_ADMIN_GROUP=timetracker-admins
|
||
- OIDC_POST_LOGOUT_REDIRECT_URI=https://your-app.example.com/
|
||
- SECRET_KEY=${SECRET_KEY}
|
||
- DATABASE_URL=${DATABASE_URL}
|
||
# ... other settings like ports/volumes
|
||
```
|
||
|
||
### 7) Security Recommendations
|
||
|
||
- Always use HTTPS in production.
|
||
- Set secure cookies: `SESSION_COOKIE_SECURE=true` in production.
|
||
- Keep the client secret in a secret store (not committed to git).
|
||
- Restrict `ADMIN_*` variables to trusted values only.
|
||
- Ensure your reverse proxy forwards `X-Forwarded-Proto` so redirects use HTTPS URLs.
|
||
|
||
### 8) Troubleshooting
|
||
|
||
- “SSO button doesn’t appear”
|
||
- Check `AUTH_METHOD`. Must be `oidc` or `both`.
|
||
|
||
- “Redirect URI mismatch”
|
||
- The `OIDC_REDIRECT_URI` must exactly match the value registered at your IdP.
|
||
|
||
- “Invalid token / missing claims”
|
||
- Confirm scopes and claim names. Override with `OIDC_*_CLAIM` envs if your IdP uses different names.
|
||
|
||
- “User is not admin”
|
||
- Verify `OIDC_ADMIN_GROUP` matches the group claim value, or add the user’s email to `OIDC_ADMIN_EMAILS`.
|
||
|
||
- "Logout keeps me signed in" or "Logout redirects to provider error page"
|
||
- Not all IdPs support RP-Initiated Logout (end-session). If your provider doesn't support it (e.g., Authelia), **do not set** `OIDC_POST_LOGOUT_REDIRECT_URI`. TimeTracker will then perform local logout only and redirect to the login page.
|
||
- If your provider supports end-session and you want to log out from the IdP too, set `OIDC_POST_LOGOUT_REDIRECT_URI` to your desired post-logout landing page.
|
||
|
||
### 9) Routes Reference
|
||
|
||
- Local login page: `GET /login` (POST for username form when enabled)
|
||
- Start OIDC login: `GET /login/oidc`
|
||
- OIDC callback: `GET /auth/oidc/callback`
|
||
- Logout: `GET /logout` (tries provider end-session if available)
|
||
|
||
### 10) Database Changes
|
||
|
||
The app includes a migration that adds the following to `users`:
|
||
|
||
- `email` (nullable)
|
||
- `oidc_issuer` (nullable)
|
||
- `oidc_sub` (nullable)
|
||
- Unique constraint on `(oidc_issuer, oidc_sub)`
|
||
|
||
If your DB wasn’t migrated automatically, run your usual migration flow.
|
||
|
||
### 11) Support
|
||
|
||
If you run into issues, capture the application logs (including the IdP error page if any) and verify your env vars. Most problems are due to a mismatch in redirect URI, missing scopes/claims, or proxy/HTTPS configuration.
|
||
|
||
|