Database & Migrations: - Add application_logs table migration for hybrid cloud logging - Add companies table migration and restructure vendor relationships Logging System: - Implement hybrid logging system (database + file) - Add log_service for centralized log management - Create admin logs page with filtering and viewing capabilities - Add init_log_settings.py script for log configuration - Enhance core logging with database integration Marketplace Integration: - Add marketplace admin page with product management - Create marketplace vendor page with product listings - Implement marketplace.js for both admin and vendor interfaces - Add marketplace integration documentation Admin Enhancements: - Add imports management page and functionality - Create settings page for admin configuration - Add vendor themes management page - Enhance vendor detail and edit pages - Improve code quality dashboard and violation details - Add logs viewing and management - Update icons guide and shared icon system Architecture & Documentation: - Document frontend structure and component architecture - Document models structure and relationships - Add vendor-in-token architecture documentation - Add vendor RBAC (role-based access control) documentation - Document marketplace integration patterns - Update architecture patterns documentation Infrastructure: - Add platform static files structure (css, img, js) - Move architecture_scan.py to proper models location - Update model imports and registrations - Enhance exception handling - Update dependency injection patterns UI/UX: - Improve vendor edit interface - Update admin user interface - Enhance page templates documentation - Add vendor marketplace interface
679 lines
15 KiB
Markdown
679 lines
15 KiB
Markdown
# Vendor RBAC System - Complete Guide
|
|
|
|
## Overview
|
|
|
|
The vendor dashboard implements a **Role-Based Access Control (RBAC)** system that distinguishes between **Owners** and **Team Members**, with granular permissions for team members.
|
|
|
|
---
|
|
|
|
## User Types
|
|
|
|
### 1. Vendor Owner
|
|
|
|
**Who:** The user who created the vendor account.
|
|
|
|
**Characteristics:**
|
|
- Has **ALL permissions** automatically (no role needed)
|
|
- Cannot be removed or have permissions restricted
|
|
- Can invite team members
|
|
- Can create and manage roles
|
|
- Identified by `VendorUser.user_type = "owner"`
|
|
- Linked via `Vendor.owner_user_id → User.id`
|
|
|
|
**Database:**
|
|
```python
|
|
# VendorUser record for owner
|
|
{
|
|
"vendor_id": 1,
|
|
"user_id": 5,
|
|
"user_type": "owner", # ✓ Owner
|
|
"role_id": None, # No role needed
|
|
"is_active": True
|
|
}
|
|
```
|
|
|
|
**Permissions:**
|
|
- ✅ **All 75 permissions** (complete access)
|
|
- See full list below
|
|
|
|
---
|
|
|
|
### 2. Team Members
|
|
|
|
**Who:** Users invited by the vendor owner to help manage the vendor.
|
|
|
|
**Characteristics:**
|
|
- Have **limited permissions** based on assigned role
|
|
- Must be invited via email
|
|
- Invitation must be accepted before activation
|
|
- Can be assigned one of the pre-defined roles or custom role
|
|
- Identified by `VendorUser.user_type = "member"`
|
|
- Permissions come from `VendorUser.role_id → Role.permissions`
|
|
|
|
**Database:**
|
|
```python
|
|
# VendorUser record for team member
|
|
{
|
|
"vendor_id": 1,
|
|
"user_id": 7,
|
|
"user_type": "member", # ✓ Team member
|
|
"role_id": 3, # ✓ Role required
|
|
"is_active": True,
|
|
"invitation_token": None, # Accepted
|
|
"invitation_accepted_at": "2024-11-15 10:30:00"
|
|
}
|
|
|
|
# Role record
|
|
{
|
|
"id": 3,
|
|
"vendor_id": 1,
|
|
"name": "Manager",
|
|
"permissions": [
|
|
"dashboard.view",
|
|
"products.view",
|
|
"products.create",
|
|
"products.edit",
|
|
"orders.view",
|
|
...
|
|
]
|
|
}
|
|
```
|
|
|
|
**Permissions:**
|
|
- 🔒 **Limited** based on assigned role
|
|
- Can have between 0 and 75 permissions
|
|
- Common roles: Manager, Staff, Support, Viewer, Marketing
|
|
|
|
---
|
|
|
|
## Permission System
|
|
|
|
### All Available Permissions (75 total)
|
|
|
|
```python
|
|
class VendorPermissions(str, Enum):
|
|
# Dashboard (1)
|
|
DASHBOARD_VIEW = "dashboard.view"
|
|
|
|
# Products (6)
|
|
PRODUCTS_VIEW = "products.view"
|
|
PRODUCTS_CREATE = "products.create"
|
|
PRODUCTS_EDIT = "products.edit"
|
|
PRODUCTS_DELETE = "products.delete"
|
|
PRODUCTS_IMPORT = "products.import"
|
|
PRODUCTS_EXPORT = "products.export"
|
|
|
|
# Stock/Inventory (3)
|
|
STOCK_VIEW = "stock.view"
|
|
STOCK_EDIT = "stock.edit"
|
|
STOCK_TRANSFER = "stock.transfer"
|
|
|
|
# Orders (4)
|
|
ORDERS_VIEW = "orders.view"
|
|
ORDERS_EDIT = "orders.edit"
|
|
ORDERS_CANCEL = "orders.cancel"
|
|
ORDERS_REFUND = "orders.refund"
|
|
|
|
# Customers (4)
|
|
CUSTOMERS_VIEW = "customers.view"
|
|
CUSTOMERS_EDIT = "customers.edit"
|
|
CUSTOMERS_DELETE = "customers.delete"
|
|
CUSTOMERS_EXPORT = "customers.export"
|
|
|
|
# Marketing (3)
|
|
MARKETING_VIEW = "marketing.view"
|
|
MARKETING_CREATE = "marketing.create"
|
|
MARKETING_SEND = "marketing.send"
|
|
|
|
# Reports (3)
|
|
REPORTS_VIEW = "reports.view"
|
|
REPORTS_FINANCIAL = "reports.financial"
|
|
REPORTS_EXPORT = "reports.export"
|
|
|
|
# Settings (4)
|
|
SETTINGS_VIEW = "settings.view"
|
|
SETTINGS_EDIT = "settings.edit"
|
|
SETTINGS_THEME = "settings.theme"
|
|
SETTINGS_DOMAINS = "settings.domains"
|
|
|
|
# Team Management (4)
|
|
TEAM_VIEW = "team.view"
|
|
TEAM_INVITE = "team.invite"
|
|
TEAM_EDIT = "team.edit"
|
|
TEAM_REMOVE = "team.remove"
|
|
|
|
# Marketplace Imports (3)
|
|
IMPORTS_VIEW = "imports.view"
|
|
IMPORTS_CREATE = "imports.create"
|
|
IMPORTS_CANCEL = "imports.cancel"
|
|
```
|
|
|
|
---
|
|
|
|
## Pre-Defined Roles
|
|
|
|
### 1. Owner (All 75 permissions)
|
|
**Use case:** Vendor owner (automatically assigned)
|
|
- ✅ Full access to everything
|
|
- ✅ Cannot be restricted
|
|
- ✅ No role record needed (permissions checked differently)
|
|
|
|
---
|
|
|
|
### 2. Manager (43 permissions)
|
|
**Use case:** Senior staff who manage most operations
|
|
|
|
**Has access to:**
|
|
- ✅ Dashboard, Products (all), Stock (all)
|
|
- ✅ Orders (all), Customers (view, edit, export)
|
|
- ✅ Marketing (all), Reports (all including financial)
|
|
- ✅ Settings (view, theme)
|
|
- ✅ Imports (all)
|
|
|
|
**Does NOT have:**
|
|
- ❌ `customers.delete` - Cannot delete customers
|
|
- ❌ `settings.edit` - Cannot change core settings
|
|
- ❌ `settings.domains` - Cannot manage domains
|
|
- ❌ `team.*` - Cannot manage team members
|
|
|
|
---
|
|
|
|
### 3. Staff (10 permissions)
|
|
**Use case:** Daily operations staff
|
|
|
|
**Has access to:**
|
|
- ✅ Dashboard view
|
|
- ✅ Products (view, create, edit)
|
|
- ✅ Stock (view, edit)
|
|
- ✅ Orders (view, edit)
|
|
- ✅ Customers (view, edit)
|
|
|
|
**Does NOT have:**
|
|
- ❌ Delete anything
|
|
- ❌ Import/export
|
|
- ❌ Marketing
|
|
- ❌ Financial reports
|
|
- ❌ Settings
|
|
- ❌ Team management
|
|
|
|
---
|
|
|
|
### 4. Support (6 permissions)
|
|
**Use case:** Customer support team
|
|
|
|
**Has access to:**
|
|
- ✅ Dashboard view
|
|
- ✅ Products (view only)
|
|
- ✅ Orders (view, edit)
|
|
- ✅ Customers (view, edit)
|
|
|
|
**Does NOT have:**
|
|
- ❌ Create/delete products
|
|
- ❌ Stock management
|
|
- ❌ Marketing
|
|
- ❌ Reports
|
|
- ❌ Settings
|
|
- ❌ Team management
|
|
|
|
---
|
|
|
|
### 5. Viewer (6 permissions)
|
|
**Use case:** Read-only access for reporting/audit
|
|
|
|
**Has access to:**
|
|
- ✅ Dashboard (view)
|
|
- ✅ Products (view)
|
|
- ✅ Stock (view)
|
|
- ✅ Orders (view)
|
|
- ✅ Customers (view)
|
|
- ✅ Reports (view)
|
|
|
|
**Does NOT have:**
|
|
- ❌ Edit anything
|
|
- ❌ Create/delete anything
|
|
- ❌ Marketing
|
|
- ❌ Financial reports
|
|
- ❌ Settings
|
|
- ❌ Team management
|
|
|
|
---
|
|
|
|
### 6. Marketing (7 permissions)
|
|
**Use case:** Marketing team focused on campaigns
|
|
|
|
**Has access to:**
|
|
- ✅ Dashboard (view)
|
|
- ✅ Customers (view, export)
|
|
- ✅ Marketing (all)
|
|
- ✅ Reports (view)
|
|
|
|
**Does NOT have:**
|
|
- ❌ Products management
|
|
- ❌ Orders management
|
|
- ❌ Stock management
|
|
- ❌ Financial reports
|
|
- ❌ Settings
|
|
- ❌ Team management
|
|
|
|
---
|
|
|
|
## Permission Checking Logic
|
|
|
|
### How Permissions Are Checked
|
|
|
|
```python
|
|
# In User model (models/database/user.py)
|
|
|
|
def has_vendor_permission(self, vendor_id: int, permission: str) -> bool:
|
|
"""Check if user has a specific permission in a vendor."""
|
|
|
|
# Step 1: Check if user is owner
|
|
if self.is_owner_of(vendor_id):
|
|
return True # ✅ Owners have ALL permissions
|
|
|
|
# Step 2: Check team member permissions
|
|
for vm in self.vendor_memberships:
|
|
if vm.vendor_id == vendor_id and vm.is_active:
|
|
if vm.role and permission in vm.role.permissions:
|
|
return True # ✅ Permission found in role
|
|
|
|
# No permission found
|
|
return False
|
|
```
|
|
|
|
### Permission Checking Flow
|
|
|
|
```
|
|
Request → Middleware → Extract vendor from URL
|
|
↓
|
|
Check user authentication
|
|
↓
|
|
Check if user is owner
|
|
├── YES → ✅ Allow (all permissions)
|
|
└── NO ↓
|
|
Check if user is team member
|
|
├── NO → ❌ Deny
|
|
└── YES ↓
|
|
Check if membership is active
|
|
├── NO → ❌ Deny
|
|
└── YES ↓
|
|
Check if role has required permission
|
|
├── NO → ❌ Deny (403 Forbidden)
|
|
└── YES → ✅ Allow
|
|
```
|
|
|
|
---
|
|
|
|
## Using Permissions in Code
|
|
|
|
### 1. Require Specific Permission
|
|
|
|
**When to use:** Endpoint needs one specific permission
|
|
|
|
```python
|
|
from fastapi import APIRouter, Depends
|
|
from app.api.deps import require_vendor_permission
|
|
from app.core.permissions import VendorPermissions
|
|
from models.database.user import User
|
|
|
|
router = APIRouter()
|
|
|
|
@router.post("/products")
|
|
def create_product(
|
|
product_data: ProductCreate,
|
|
user: User = Depends(
|
|
require_vendor_permission(VendorPermissions.PRODUCTS_CREATE.value)
|
|
)
|
|
):
|
|
"""
|
|
Create a product.
|
|
|
|
Required permission: products.create
|
|
✅ Owner: Always allowed
|
|
✅ Manager: Allowed (has products.create)
|
|
✅ Staff: Allowed (has products.create)
|
|
❌ Support: Denied (no products.create)
|
|
❌ Viewer: Denied (no products.create)
|
|
❌ Marketing: Denied (no products.create)
|
|
"""
|
|
# Create product...
|
|
pass
|
|
```
|
|
|
|
---
|
|
|
|
### 2. Require ANY Permission
|
|
|
|
**When to use:** Endpoint can be accessed with any of several permissions
|
|
|
|
```python
|
|
@router.get("/dashboard")
|
|
def view_dashboard(
|
|
user: User = Depends(
|
|
require_any_vendor_permission(
|
|
VendorPermissions.DASHBOARD_VIEW.value,
|
|
VendorPermissions.REPORTS_VIEW.value
|
|
)
|
|
)
|
|
):
|
|
"""
|
|
View dashboard.
|
|
|
|
Required: dashboard.view OR reports.view
|
|
✅ Owner: Always allowed
|
|
✅ Manager: Allowed (has both)
|
|
✅ Staff: Allowed (has dashboard.view)
|
|
✅ Support: Allowed (has dashboard.view)
|
|
✅ Viewer: Allowed (has both)
|
|
✅ Marketing: Allowed (has both)
|
|
"""
|
|
# Show dashboard...
|
|
pass
|
|
```
|
|
|
|
---
|
|
|
|
### 3. Require ALL Permissions
|
|
|
|
**When to use:** Endpoint needs multiple permissions
|
|
|
|
```python
|
|
@router.post("/products/bulk-delete")
|
|
def bulk_delete_products(
|
|
user: User = Depends(
|
|
require_all_vendor_permissions(
|
|
VendorPermissions.PRODUCTS_VIEW.value,
|
|
VendorPermissions.PRODUCTS_DELETE.value
|
|
)
|
|
)
|
|
):
|
|
"""
|
|
Bulk delete products.
|
|
|
|
Required: products.view AND products.delete
|
|
✅ Owner: Always allowed
|
|
✅ Manager: Allowed (has both)
|
|
❌ Staff: Denied (no products.delete)
|
|
❌ Support: Denied (no products.delete)
|
|
❌ Viewer: Denied (no products.delete)
|
|
❌ Marketing: Denied (no products.delete)
|
|
"""
|
|
# Delete products...
|
|
pass
|
|
```
|
|
|
|
---
|
|
|
|
### 4. Require Owner Only
|
|
|
|
**When to use:** Endpoint is owner-only (team management, critical settings)
|
|
|
|
```python
|
|
from app.api.deps import require_vendor_owner
|
|
|
|
@router.post("/team/invite")
|
|
def invite_team_member(
|
|
email: str,
|
|
role_id: int,
|
|
user: User = Depends(require_vendor_owner)
|
|
):
|
|
"""
|
|
Invite a team member.
|
|
|
|
Required: Must be vendor owner
|
|
✅ Owner: Allowed
|
|
❌ Manager: Denied (not owner)
|
|
❌ All team members: Denied (not owner)
|
|
"""
|
|
# Invite team member...
|
|
pass
|
|
```
|
|
|
|
---
|
|
|
|
### 5. Get User Permissions
|
|
|
|
**When to use:** Need to check permissions in business logic
|
|
|
|
```python
|
|
from app.api.deps import get_user_permissions
|
|
|
|
@router.get("/my-permissions")
|
|
def list_my_permissions(
|
|
permissions: list = Depends(get_user_permissions)
|
|
):
|
|
"""
|
|
Get all permissions for current user.
|
|
|
|
Returns:
|
|
- Owner: All 75 permissions
|
|
- Team Member: Permissions from their role
|
|
"""
|
|
return {"permissions": permissions}
|
|
```
|
|
|
|
---
|
|
|
|
## Database Schema
|
|
|
|
### VendorUser Table
|
|
|
|
```sql
|
|
CREATE TABLE vendor_users (
|
|
id SERIAL PRIMARY KEY,
|
|
vendor_id INTEGER NOT NULL REFERENCES vendors(id),
|
|
user_id INTEGER NOT NULL REFERENCES users(id),
|
|
user_type VARCHAR NOT NULL, -- 'owner' or 'member'
|
|
role_id INTEGER REFERENCES roles(id), -- NULL for owners
|
|
invited_by INTEGER REFERENCES users(id),
|
|
invitation_token VARCHAR,
|
|
invitation_sent_at TIMESTAMP,
|
|
invitation_accepted_at TIMESTAMP,
|
|
is_active BOOLEAN DEFAULT FALSE,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
```
|
|
|
|
### Role Table
|
|
|
|
```sql
|
|
CREATE TABLE roles (
|
|
id SERIAL PRIMARY KEY,
|
|
vendor_id INTEGER NOT NULL REFERENCES vendors(id),
|
|
name VARCHAR(100) NOT NULL,
|
|
permissions JSON DEFAULT '[]', -- Array of permission strings
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## Team Member Lifecycle
|
|
|
|
### 1. Invitation
|
|
|
|
```
|
|
Owner invites user → VendorUser created:
|
|
{
|
|
"user_type": "member",
|
|
"is_active": False,
|
|
"invitation_token": "abc123...",
|
|
"invitation_sent_at": "2024-11-29 10:00:00",
|
|
"invitation_accepted_at": null
|
|
}
|
|
```
|
|
|
|
### 2. Acceptance
|
|
|
|
```
|
|
User accepts invitation → VendorUser updated:
|
|
{
|
|
"is_active": True,
|
|
"invitation_token": null,
|
|
"invitation_accepted_at": "2024-11-29 10:30:00"
|
|
}
|
|
```
|
|
|
|
### 3. Active Member
|
|
|
|
```
|
|
Member can now access vendor dashboard with role permissions
|
|
```
|
|
|
|
### 4. Deactivation
|
|
|
|
```
|
|
Owner deactivates member → VendorUser updated:
|
|
{
|
|
"is_active": False
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Common Use Cases
|
|
|
|
### Use Case 1: Dashboard Access
|
|
|
|
**Q:** Can all users access the dashboard?
|
|
|
|
**A:** Yes, if they have `dashboard.view` permission.
|
|
|
|
- ✅ Owner: Always
|
|
- ✅ Manager, Staff, Support, Viewer, Marketing: All have it
|
|
- ❌ Custom role without `dashboard.view`: No
|
|
|
|
---
|
|
|
|
### Use Case 2: Product Management
|
|
|
|
**Q:** Who can create products?
|
|
|
|
**A:** Users with `products.create` permission.
|
|
|
|
- ✅ Owner: Always
|
|
- ✅ Manager: Yes (has permission)
|
|
- ✅ Staff: Yes (has permission)
|
|
- ❌ Support, Viewer, Marketing: No
|
|
|
|
---
|
|
|
|
### Use Case 3: Financial Reports
|
|
|
|
**Q:** Who can view financial reports?
|
|
|
|
**A:** Users with `reports.financial` permission.
|
|
|
|
- ✅ Owner: Always
|
|
- ✅ Manager: Yes (has permission)
|
|
- ❌ Staff, Support, Viewer, Marketing: No
|
|
|
|
---
|
|
|
|
### Use Case 4: Team Management
|
|
|
|
**Q:** Who can invite team members?
|
|
|
|
**A:** Only the vendor owner.
|
|
|
|
- ✅ Owner: Yes (owner-only operation)
|
|
- ❌ All team members (including Manager): No
|
|
|
|
---
|
|
|
|
### Use Case 5: Settings Changes
|
|
|
|
**Q:** Who can change vendor settings?
|
|
|
|
**A:** Users with `settings.edit` permission.
|
|
|
|
- ✅ Owner: Always
|
|
- ❌ Manager: No (doesn't have permission)
|
|
- ❌ All other roles: No
|
|
|
|
---
|
|
|
|
## Error Responses
|
|
|
|
### Missing Permission
|
|
|
|
```http
|
|
HTTP 403 Forbidden
|
|
|
|
{
|
|
"error_code": "INSUFFICIENT_VENDOR_PERMISSIONS",
|
|
"message": "You don't have permission to perform this action",
|
|
"details": {
|
|
"required_permission": "products.delete",
|
|
"vendor_code": "wizamart"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Not Owner
|
|
|
|
```http
|
|
HTTP 403 Forbidden
|
|
|
|
{
|
|
"error_code": "VENDOR_OWNER_ONLY",
|
|
"message": "This operation requires vendor owner privileges",
|
|
"details": {
|
|
"operation": "team management",
|
|
"vendor_code": "wizamart"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Inactive Membership
|
|
|
|
```http
|
|
HTTP 403 Forbidden
|
|
|
|
{
|
|
"error_code": "INACTIVE_VENDOR_MEMBERSHIP",
|
|
"message": "Your vendor membership is inactive"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
### Owner vs Team Member
|
|
|
|
| Feature | Owner | Team Member |
|
|
|---------|-------|-------------|
|
|
| **Permissions** | All 75 (automatic) | Based on role (0-75) |
|
|
| **Role Required** | No | Yes |
|
|
| **Can Be Removed** | No | Yes |
|
|
| **Team Management** | ✅ Yes | ❌ No |
|
|
| **Critical Settings** | ✅ Yes | ❌ No (usually) |
|
|
| **Invitation Required** | No (creates vendor) | Yes |
|
|
|
|
### Permission Hierarchy
|
|
|
|
```
|
|
Owner (75 permissions)
|
|
└─ Manager (43 permissions)
|
|
└─ Staff (10 permissions)
|
|
└─ Support (6 permissions)
|
|
└─ Viewer (6 permissions, read-only)
|
|
|
|
Marketing (7 permissions, specialized)
|
|
```
|
|
|
|
### Best Practices
|
|
|
|
1. **Use Constants:** Always use `VendorPermissions.PERMISSION_NAME.value`
|
|
2. **Least Privilege:** Give team members minimum permissions needed
|
|
3. **Owner Only:** Keep sensitive operations owner-only
|
|
4. **Custom Roles:** Create custom roles for specific needs
|
|
5. **Regular Audit:** Review team member permissions regularly
|
|
|
|
---
|
|
|
|
This RBAC system provides flexible, secure access control for vendor dashboards with clear separation between owners and team members.
|