8.0 KiB
8.0 KiB
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
- User visits the app → Redirected to
/login - User enters username and password
- System validates credentials against
users.json - System checks if user account is active
- 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 pagePOST /api/login- Login endpointGET /users- User management page
Protected Routes (Login Required)
GET /- Main product finder appGET /quiz- Quiz page (alias for main app)GET /image-test- Image generation test pageGET /select-location- Location selection pagePOST /api/select-location- Set current location
Session Routes
GET /api/session- Get current session infoPOST /api/logout- Logout and clear session
API Endpoints
POST /api/login
Authenticate user and create session.
Request:
{
"username": "john_doe",
"password": "password123"
}
Success Response:
{
"status": "success",
"message": "Login successful",
"requiresLocationSelection": true
}
Error Responses:
{
"status": "error",
"message": "Invalid username or password"
}
{
"status": "error",
"message": "Account is inactive. Please contact an administrator."
}
GET /api/session
Get current user session information.
Response:
{
"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:
{
"location": "KC"
}
Response:
{
"status": "success",
"message": "Location selected",
"currentLocation": "KC"
}
POST /api/logout
Log out and clear session.
Response:
{
"status": "success",
"message": "Logged out successfully"
}
Session Data
The session stores:
user_id: Index of user in users.jsonusername: Username stringdefaultLocation: User's default location codecurrentLocation: Currently selected location codeaccessibleLocations: Array of location codes user can access
Authentication Decorator
The @login_required decorator protects routes:
@app.route('/protected-page')
@login_required
def protected_page():
return render_template('protected.html')
The decorator:
- Checks if user is logged in (has
user_idin session) - Validates user still exists in users.json
- Checks if user account is still active
- Redirects to login if any check fails
Getting Current User in Routes
@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:
# 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
- Go to
/users - Create a test user:
- Username:
testuser - Password:
password123 - Default Location: Lindsborg
- Check "Accessible" for Lindsborg and KC
- Username:
Test Login Flow
- Go to
/(should redirect to/login) - Enter credentials:
testuser/password123 - Click "Sign In"
- Since user has 2 accessible locations → redirected to
/select-location - Choose a location and click "Continue"
- Now viewing main Product Finder app
- See user info in header
- Click "Logout" to end session
Test Single Location User
- Create user with only 1 accessible location
- Log in
- Should go directly to main app (skip location selection)
Test Inactive User
- Create and log in as a user
- In User Management, toggle user to "Inactive"
- 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