Files
CGW-Quote-Builder/information/LOGIN_SYSTEM_README.md
T
2026-04-11 00:04:09 -05:00

313 lines
8.0 KiB
Markdown

# Login System Documentation
## Overview
A complete authentication system for the CGW Product Finder that integrates with the user management system. Users must log in with their credentials to access the product finder application.
## Features
### 🔐 Secure Authentication
- Password verification using PBKDF2-SHA256 hashing
- Session-based authentication with HTTP-only cookies
- Automatic session management
- Active/inactive user account checking
### 📍 Multi-Location Support
- Automatic location selection for single-location users
- Location selection page for users with multiple accessible locations
- Default location preference
- Location-based access control
### 🛡️ Security Features
- Login required decorator protects all main routes
- Inactive accounts are automatically blocked
- Sessions expire on logout or server restart
- Secure session cookies (HTTP-only, SameSite)
## User Flow
### 1. Login Process
1. User visits the app → Redirected to `/login`
2. User enters **username** and **password**
3. System validates credentials against `users.json`
4. System checks if user account is **active**
5. If valid and active:
- Session is created
- User accessible locations are loaded
### 2. Location Selection (if applicable)
- **Single Accessible Location**: User goes directly to main app (location selection bypassed)
- **Multiple Accessible Locations**: User is redirected to `/select-location`
- Shows all accessible locations
- Default location is pre-selected
- User can choose their working location
- Selection is saved to session
- **Note**: Default location is automatically marked as accessible when user is created
### 3. Main Application Access
- User accesses the Product Finder
- User info displayed in header (username + current location)
- Logout button available in header
## Routes
### Public Routes (No Login Required)
- `GET /login` - Login page
- `POST /api/login` - Login endpoint
- `GET /users` - User management page
### Protected Routes (Login Required)
- `GET /` - Main product finder app
- `GET /quiz` - Quiz page (alias for main app)
- `GET /image-test` - Image generation test page
- `GET /select-location` - Location selection page
- `POST /api/select-location` - Set current location
### Session Routes
- `GET /api/session` - Get current session info
- `POST /api/logout` - Logout and clear session
## API Endpoints
### POST /api/login
Authenticate user and create session.
**Request:**
```json
{
"username": "john_doe",
"password": "password123"
}
```
**Success Response:**
```json
{
"status": "success",
"message": "Login successful",
"requiresLocationSelection": true
}
```
**Error Responses:**
```json
{
"status": "error",
"message": "Invalid username or password"
}
```
```json
{
"status": "error",
"message": "Account is inactive. Please contact an administrator."
}
```
### GET /api/session
Get current user session information.
**Response:**
```json
{
"status": "success",
"username": "john_doe",
"defaultLocation": "LINDS",
"currentLocation": "KC",
"accessibleLocations": ["LINDS", "KC", "IOLA"]
}
```
### POST /api/select-location
Select a location for the current session.
**Request:**
```json
{
"location": "KC"
}
```
**Response:**
```json
{
"status": "success",
"message": "Location selected",
"currentLocation": "KC"
}
```
### POST /api/logout
Log out and clear session.
**Response:**
```json
{
"status": "success",
"message": "Logged out successfully"
}
```
## Session Data
The session stores:
- `user_id`: Index of user in users.json
- `username`: Username string
- `defaultLocation`: User's default location code
- `currentLocation`: Currently selected location code
- `accessibleLocations`: Array of location codes user can access
## Authentication Decorator
The `@login_required` decorator protects routes:
```python
@app.route('/protected-page')
@login_required
def protected_page():
return render_template('protected.html')
```
The decorator:
1. Checks if user is logged in (has `user_id` in session)
2. Validates user still exists in users.json
3. Checks if user account is still active
4. Redirects to login if any check fails
## Getting Current User in Routes
```python
@app.route('/my-route')
@login_required
def my_route():
user = get_current_user()
username = session.get('username')
current_location = session.get('currentLocation')
# Use user data...
return render_template('page.html')
```
## Location-Based Access Control
Users can only access locations they have permission for:
```python
# In users.json
{
"username": "john_doe",
"locationSettings": {
"LINDS": { "accessible": true },
"IOLA": { "accessible": false },
"KC": { "accessible": true },
"BMD": { "accessible": false }
}
}
```
This user can access:
- ✅ Lindsborg (LINDS)
- ✅ KC (KC)
- ❌ Iola (IOLA)
- ❌ BMD (BMD)
## User Interface Components
### Login Page (`/login`)
- Clean, centered login form
- Username and password fields
- Submit button with loading spinner
- Link to User Management page
- Error message display
### Location Selection Page (`/select-location`)
- Shows logged-in username
- Shows default location
- Radio buttons for each accessible location
- Default location is pre-selected
- Continue and Logout buttons
### Main App Header
- User info display: `👤 username | 📍 location`
- Logout button in header
- Positioned in top-right corner
## Security Considerations
### Password Security
- Passwords are hashed using PBKDF2-SHA256
- Hashes are never reversed or displayed
- Hash verification happens server-side only
### Session Security
- Sessions use secure random keys
- Cookies are HTTP-only (not accessible via JavaScript)
- SameSite cookie policy prevents CSRF attacks
- Sessions cleared on logout
### Account Status
- Inactive accounts cannot log in
- If account is deactivated while logged in, next request will log them out
- User must have at least one accessible location
## Testing the Login System
### Test User Creation
1. Go to `/users`
2. Create a test user:
- Username: `testuser`
- Password: `password123`
- Default Location: Lindsborg
- Check "Accessible" for Lindsborg and KC
### Test Login Flow
1. Go to `/` (should redirect to `/login`)
2. Enter credentials: `testuser` / `password123`
3. Click "Sign In"
4. Since user has 2 accessible locations → redirected to `/select-location`
5. Choose a location and click "Continue"
6. Now viewing main Product Finder app
7. See user info in header
8. Click "Logout" to end session
### Test Single Location User
1. Create user with only 1 accessible location
2. Log in
3. Should go directly to main app (skip location selection)
### Test Inactive User
1. Create and log in as a user
2. In User Management, toggle user to "Inactive"
3. Try to log in → Should see "Account is inactive" message
## Troubleshooting
### "Please log in first" on all pages
- Session may have expired
- Server may have restarted (sessions are in-memory)
- Clear browser cookies and log in again
### "User not found" error
- User may have been deleted while logged in
- Log out and log back in
### Can't access certain locations
- Check user's "Accessible" checkboxes in User Management
- User must have at least one accessible location
### Stuck on location selection page
- User must have multiple accessible locations
- If this shouldn't happen, check user's location settings
- Or click "Sign Out" and contact administrator
## Future Enhancements
Potential additions:
- [ ] Remember me checkbox (persistent sessions)
- [ ] Password reset functionality
- [ ] Session timeout after inactivity
- [ ] Login attempt limiting (brute force protection)
- [ ] Two-factor authentication
- [ ] Session management dashboard
- [ ] Location switching without re-login
- [ ] Audit log of login attempts