Initial
This commit is contained in:
@@ -0,0 +1,264 @@
|
||||
# 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)
|
||||
|
||||
```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)
|
||||
|
||||
```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
|
||||
```bash
|
||||
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
|
||||
```bash
|
||||
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
|
||||
```bash
|
||||
# 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
|
||||
```bash
|
||||
# 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**
|
||||
```python
|
||||
# Choose a descriptive name like 'create_quotes'
|
||||
```
|
||||
|
||||
2. **Protect Backend Route**
|
||||
```python
|
||||
@app.route('/quotes/new')
|
||||
@login_required
|
||||
@permission_required('create_quotes')
|
||||
def new_quote():
|
||||
return render_template('new_quote.html')
|
||||
```
|
||||
|
||||
3. **Check in Code**
|
||||
```python
|
||||
if can_user('create_quotes'):
|
||||
# Allow quote creation
|
||||
```
|
||||
|
||||
4. **Hide/Show Frontend Elements**
|
||||
```javascript
|
||||
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**
|
||||
```json
|
||||
{
|
||||
"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!
|
||||
Reference in New Issue
Block a user