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:
-
Permission Checking Functions (Backend - Python)
can_user(permission, location=None)- Check single permissionuser_has_any_permission(permissions, location=None)- Check if user has ANY permissionuser_has_all_permissions(permissions, location=None)- Check if user has ALL permissionsget_user_permissions(location=None)- Get all user permissions@permission_required(permission, location=None)- Route decorator for permission protection
-
Permission Check Endpoints (Frontend - API)
POST /api/check-permission- Check if user has specific permissionGET /api/user-permissions- Get all user permissions
-
Access Denial
- Beautiful access denied page at
templates/access_denied.html - Shows required permission and helpful navigation
- Beautiful access denied page at
-
Protected Routes
/users- User management page (requiresmanage_users)/api/users(GET, POST, PATCH, DELETE) - All user management endpoints protected
-
User Data Structure
- Global permissions:
user.permissions - Location-specific permissions:
user.locationSettings[LOCATION].permissions
- Global 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 pageapp/PERMISSIONS_SYSTEM.md- Comprehensive documentation
Modified:
app/app.py- Added permission checking functions and protected routesapp/data/users.json- Added permissions to existing usersapp/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 listreset_passwords- Reset passwords
Products & Inventory:
manage_products- Add/edit/delete productsview_products- View product catalogmanage_inventory- Adjust inventoryview_inventory- View inventory
Quotes & Orders:
create_quotes- Create quotesview_quotes- View quotesapprove_quotes- Approve/reject quotesedit_quotes- Edit quotes
Reports:
view_reports- Access reportsexport_data- Export dataview_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:
-
Define Permission Name
# Choose a descriptive name like 'create_quotes' -
Protect Backend Route
@app.route('/quotes/new') @login_required @permission_required('create_quotes') def new_quote(): return render_template('new_quote.html') -
Check in Code
if can_user('create_quotes'): # Allow quote creation -
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'; } -
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!