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

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

  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:

{
  "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.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:

@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

@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

  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