Files
2026-04-11 00:04:09 -05:00

7.4 KiB

WordPress-Style Permission System - Quick Reference

What Was Implemented

The CGW Product Finder now has a complete WordPress-style permission system with:

  1. Permission Checking Functions (Backend - Python)

    • can_user(permission, location=None) - Check single permission
    • user_has_any_permission(permissions, location=None) - Check if user has ANY permission
    • user_has_all_permissions(permissions, location=None) - Check if user has ALL permissions
    • get_user_permissions(location=None) - Get all user permissions
    • @permission_required(permission, location=None) - Route decorator for permission protection
  2. Permission Check Endpoints (Frontend - API)

    • POST /api/check-permission - Check if user has specific permission
    • GET /api/user-permissions - Get all user permissions
  3. Access Denial

    • Beautiful access denied page at templates/access_denied.html
    • Shows required permission and helpful navigation
  4. Protected Routes

    • /users - User management page (requires manage_users)
    • /api/users (GET, POST, PATCH, DELETE) - All user management endpoints protected
  5. User Data Structure

    • Global permissions: user.permissions
    • Location-specific permissions: user.locationSettings[LOCATION].permissions

🚀 Quick Start Usage

Backend (Python)

# Check permission
if can_user('create_quotes'):
    # User can create quotes
    pass

# Protect a route
@app.route('/admin/reports')
@login_required
@permission_required('view_reports')
def admin_reports():
    return render_template('reports.html')

# Check at specific location
if can_user('manage_inventory', location='LINDS'):
    # User can manage inventory at Lindsborg
    pass

Frontend (JavaScript)

// Check single permission
const response = await fetch('/api/check-permission', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ permission: 'create_quotes' })
});
const data = await response.json();
if (data.hasPermission) {
    // Show create button
}

// Get all permissions
const response = await fetch('/api/user-permissions');
const data = await response.json();
console.log(data.permissions); // { manage_users: true, create_quotes: true, ... }

📁 Files Modified/Created

Created:

  • app/templates/access_denied.html - Access denial page
  • app/PERMISSIONS_SYSTEM.md - Comprehensive documentation

Modified:

  • app/app.py - Added permission checking functions and protected routes
  • app/data/users.json - Added permissions to existing users
  • app/data/example_user_structure.json - Updated with permission examples

👥 Current Users & Permissions

Master (Admin)

  • Password: Master
  • Location: KC (access to all locations)
  • Permissions: Full access
    • manage_users
    • view_reports
    • create_quotes
    • approve_quotes
    • manage_products
    • manage_inventory

Darlene (Standard User)

  • Password: Darlene
  • Location: IOLA (access to LINDS, IOLA, KC)
  • Permissions: Limited access
    • manage_users
    • view_reports
    • create_quotes
    • approve_quotes
    • manage_products
    • manage_inventory

🔒 Permission Hierarchy

Check Order:
1. Is user logged in? → If no: return False
2. Is user active? → If no: return False
3. Check global permissions (user.permissions) → If found: return value
4. Check location-specific permissions → If found: return value
5. Default: return False

🎯 Common Permission Names

Recommended permissions for your system:

User Management:

  • manage_users - Create, edit, delete users (already implemented)
  • view_users - View user list
  • reset_passwords - Reset passwords

Products & Inventory:

  • manage_products - Add/edit/delete products
  • view_products - View product catalog
  • manage_inventory - Adjust inventory
  • view_inventory - View inventory

Quotes & Orders:

  • create_quotes - Create quotes
  • view_quotes - View quotes
  • approve_quotes - Approve/reject quotes
  • edit_quotes - Edit quotes

Reports:

  • view_reports - Access reports
  • export_data - Export data
  • view_analytics - View analytics

🧪 Testing the System

Test 1: User Management Access

1. Start Flask server: python app/app.py
2. Login as Master (password: Master)
3. Navigate to /users
4. Should see user management interface ✅

Test 2: Permission Denied

1. Create a new user without manage_users permission
2. Login as that user
3. Navigate to /users
4. Should see "Access Denied" page ✅

Test 3: API Permission Check

# In browser console after login:
const response = await fetch('/api/check-permission', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({permission: 'manage_users'})
});
const data = await response.json();
console.log(data.hasPermission); // Should be true for Master

Test 4: Get All Permissions

# In browser console after login:
const response = await fetch('/api/user-permissions');
const data = await response.json();
console.log(data.permissions); // Should show all user's permissions

📝 Next Steps

To add permissions to new features:

  1. Define Permission Name

    # Choose a descriptive name like 'create_quotes'
    
  2. Protect Backend Route

    @app.route('/quotes/new')
    @login_required
    @permission_required('create_quotes')
    def new_quote():
        return render_template('new_quote.html')
    
  3. Check in Code

    if can_user('create_quotes'):
        # Allow quote creation
    
  4. Hide/Show Frontend Elements

    const perms = await fetch('/api/user-permissions').then(r => r.json());
    if (perms.permissions.create_quotes) {
        document.getElementById('createBtn').style.display = 'block';
    }
    
  5. Add to User Data

    {
      "username": "user",
      "permissions": {
        "create_quotes": true
      }
    }
    

🛠️ Troubleshooting

Access Denied even with permission:

  • Check spelling of permission name (case-sensitive)
  • Verify user is active in users.json
  • Clear browser cookies and re-login
  • Check server logs for errors

Permission check returns False:

  • Ensure user is logged in
  • Verify permission exists in users.json
  • Check if using correct location context
  • Confirm session is valid

Frontend shows button but backend denies:

  • This is correct! Frontend checks are for UX only
  • Backend always enforces permissions
  • Never trust client-side permission checks

📚 Full Documentation

See app/PERMISSIONS_SYSTEM.md for complete documentation including:

  • Detailed examples
  • Best practices
  • Security notes
  • Migration guide
  • Advanced usage patterns

🎉 Summary

You now have a fully functional WordPress-style permission system that allows:

  • Fine-grained access control
  • Global and location-specific permissions
  • Easy permission checks in code
  • Protected routes with decorators
  • Frontend permission checking
  • Beautiful access denied pages
  • Flexible permission inheritance

The system is secure, scalable, and follows WordPress best practices!