423 lines
11 KiB
Markdown
423 lines
11 KiB
Markdown
# Authentication and Authorization Plan for Django Manufacturing App
|
|
|
|
## Overview
|
|
This document outlines the authentication and authorization system for the manufacturing application, including user roles, permissions, and access control mechanisms.
|
|
|
|
## Authentication System
|
|
|
|
### 1. Custom User Model
|
|
```python
|
|
# accounts/models.py
|
|
|
|
from django.contrib.auth.models import AbstractUser
|
|
from django.db import models
|
|
|
|
class User(AbstractUser):
|
|
phone = models.CharField(max_length=20, blank=True)
|
|
department = models.CharField(max_length=100, blank=True)
|
|
position = models.CharField(max_length=100, blank=True)
|
|
is_active = models.BooleanField(default=True)
|
|
date_joined = models.DateTimeField(auto_now_add=True)
|
|
|
|
def __str__(self):
|
|
return self.username
|
|
|
|
@property
|
|
def full_name(self):
|
|
return f"{self.first_name} {self.last_name}".strip() or self.username
|
|
|
|
def has_module_access(self, module_name):
|
|
"""Check if user has access to a specific module"""
|
|
if self.is_superuser:
|
|
return True
|
|
return self.groups.filter(permissions__codename__icontains=module_name).exists()
|
|
```
|
|
|
|
### 2. Authentication Views
|
|
```python
|
|
# accounts/views.py
|
|
|
|
from django.contrib.auth import authenticate, login, logout
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.shortcuts import render, redirect
|
|
from django.contrib import messages
|
|
from .forms import LoginForm
|
|
|
|
def login_view(request):
|
|
if request.method == 'POST':
|
|
form = LoginForm(request.POST)
|
|
if form.is_valid():
|
|
username = form.cleaned_data['username']
|
|
password = form.cleaned_data['password']
|
|
user = authenticate(request, username=username, password=password)
|
|
if user is not None:
|
|
login(request, user)
|
|
next_url = request.GET.get('next', 'dashboard:home')
|
|
return redirect(next_url)
|
|
else:
|
|
messages.error(request, 'Invalid username or password.')
|
|
else:
|
|
form = LoginForm()
|
|
|
|
return render(request, 'accounts/login.html', {'form': form})
|
|
|
|
@login_required
|
|
def logout_view(request):
|
|
logout(request)
|
|
messages.info(request, 'You have been logged out.')
|
|
return redirect('accounts:login')
|
|
```
|
|
|
|
## Authorization System
|
|
|
|
### 3. Permission Structure
|
|
The application will use Django's built-in permission system with custom permissions for each module:
|
|
|
|
#### Core Permissions:
|
|
- `view_module`: Can view module data
|
|
- `add_module`: Can create new records
|
|
- `change_module`: Can edit existing records
|
|
- `delete_module`: Can delete records
|
|
|
|
#### Module-specific Permissions:
|
|
|
|
**User Management:**
|
|
- `view_user`
|
|
- `add_user`
|
|
- `change_user`
|
|
- `delete_user`
|
|
- `view_role`
|
|
- `add_role`
|
|
- `change_role`
|
|
- `delete_role`
|
|
|
|
**Inventory Management:**
|
|
- `view_product`
|
|
- `add_product`
|
|
- `change_product`
|
|
- `delete_product`
|
|
- `view_inventory`
|
|
- `change_inventory`
|
|
- `view_stockmovement`
|
|
- `add_stockmovement`
|
|
|
|
**Purchasing:**
|
|
- `view_supplier`
|
|
- `add_supplier`
|
|
- `change_supplier`
|
|
- `delete_supplier`
|
|
- `view_purchaseorder`
|
|
- `add_purchaseorder`
|
|
- `change_purchaseorder`
|
|
- `delete_purchaseorder`
|
|
- `view_goodsreceipt`
|
|
- `add_goodsreceipt`
|
|
|
|
**Sales:**
|
|
- `view_customer`
|
|
- `add_customer`
|
|
- `change_customer`
|
|
- `delete_customer`
|
|
- `view_salesorder`
|
|
- `add_salesorder`
|
|
- `change_salesorder`
|
|
- `delete_salesorder`
|
|
- `view_delivery`
|
|
- `add_delivery`
|
|
|
|
**Manufacturing:**
|
|
- `view_billofmaterial`
|
|
- `add_billofmaterial`
|
|
- `change_billofmaterial`
|
|
- `delete_billofmaterial`
|
|
- `view_manufacturingorder`
|
|
- `add_manufacturingorder`
|
|
- `change_manufacturingorder`
|
|
- `delete_manufacturingorder`
|
|
|
|
**Database Management:**
|
|
- `view_databasebackup`
|
|
- `add_databasebackup`
|
|
- `change_databasebackup`
|
|
- `delete_databasebackup`
|
|
- `can_backup_database`
|
|
- `can_restore_database`
|
|
- `can_initialize_database`
|
|
|
|
**Reports:**
|
|
- `view_report`
|
|
- `generate_report`
|
|
- `export_report`
|
|
|
|
**Dashboard:**
|
|
- `view_dashboard`
|
|
- `customize_dashboard`
|
|
|
|
### 4. Role Definitions
|
|
|
|
#### Superuser
|
|
- Has all permissions by default
|
|
- Can access all modules
|
|
- Can manage users and roles
|
|
- Can perform database management operations
|
|
|
|
#### Administrator
|
|
- Can access all modules except database management
|
|
- Can manage users (except other administrators)
|
|
- Can generate and export reports
|
|
- Can customize dashboard
|
|
|
|
#### Manager
|
|
- Can view and manage data in all business modules
|
|
- Cannot delete critical records
|
|
- Can generate reports
|
|
- Limited dashboard customization
|
|
|
|
#### Supervisor
|
|
- Can view and manage data in assigned modules
|
|
- Cannot create or delete records
|
|
- Can view reports
|
|
- Basic dashboard access
|
|
|
|
#### Staff
|
|
- Limited access to specific modules
|
|
- Can view and update assigned records
|
|
- Cannot access reports or dashboard customization
|
|
|
|
### 5. Permission Assignment
|
|
|
|
#### Creating Permissions in Models
|
|
```python
|
|
# inventory/models.py
|
|
|
|
from django.db import models
|
|
|
|
class Product(models.Model):
|
|
code = models.CharField(max_length=50, unique=True)
|
|
name = models.CharField(max_length=200)
|
|
# ... other fields
|
|
|
|
class Meta:
|
|
permissions = [
|
|
("view_product", "Can view product"),
|
|
("add_product", "Can add product"),
|
|
("change_product", "Can change product"),
|
|
("delete_product", "Can delete product"),
|
|
]
|
|
```
|
|
|
|
#### Group-based Permission Management
|
|
```python
|
|
# accounts/management/commands/create_groups.py
|
|
|
|
from django.core.management.base import BaseCommand
|
|
from django.contrib.auth.models import Group, Permission
|
|
from django.contrib.contenttypes.models import ContentType
|
|
|
|
class Command(BaseCommand):
|
|
help = 'Create user groups with appropriate permissions'
|
|
|
|
def handle(self, *args, **options):
|
|
# Create groups
|
|
admin_group, created = Group.objects.get_or_create(name='Administrator')
|
|
manager_group, created = Group.objects.get_or_create(name='Manager')
|
|
supervisor_group, created = Group.objects.get_or_create(name='Supervisor')
|
|
staff_group, created = Group.objects.get_or_create(name='Staff')
|
|
|
|
# Assign permissions to Administrator group
|
|
# (Can access all modules except database management)
|
|
admin_permissions = Permission.objects.exclude(
|
|
content_type__app_label='database_management'
|
|
).exclude(
|
|
codename__in=['can_backup_database', 'can_restore_database', 'can_initialize_database']
|
|
)
|
|
admin_group.permissions.set(admin_permissions)
|
|
|
|
# Assign permissions to other groups as needed
|
|
# ...
|
|
|
|
self.stdout.write(
|
|
self.style.SUCCESS('Successfully created user groups')
|
|
)
|
|
```
|
|
|
|
### 6. Permission Checking in Views
|
|
|
|
#### Function-based Views
|
|
```python
|
|
# inventory/views.py
|
|
|
|
from django.contrib.auth.decorators import login_required, permission_required
|
|
from django.shortcuts import render
|
|
|
|
@login_required
|
|
@permission_required('inventory.view_product', raise_exception=True)
|
|
def product_list_view(request):
|
|
products = Product.objects.all()
|
|
return render(request, 'inventory/product_list.html', {'products': products})
|
|
|
|
@login_required
|
|
@permission_required('inventory.add_product', raise_exception=True)
|
|
def create_product_view(request):
|
|
# Create product logic
|
|
pass
|
|
```
|
|
|
|
#### Class-based Views
|
|
```python
|
|
# purchasing/views.py
|
|
|
|
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
|
from django.views.generic import ListView, CreateView
|
|
|
|
class PurchaseOrderListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
|
model = PurchaseOrder
|
|
template_name = 'purchasing/po_list.html'
|
|
context_object_name = 'purchase_orders'
|
|
permission_required = 'purchasing.view_purchaseorder'
|
|
|
|
def handle_no_permission(self):
|
|
messages.error(self.request, 'You do not have permission to view purchase orders.')
|
|
return redirect('dashboard:home')
|
|
```
|
|
|
|
### 7. Custom Permission Mixins
|
|
|
|
```python
|
|
# accounts/mixins.py
|
|
|
|
from django.contrib.auth.mixins import AccessMixin
|
|
from django.contrib import messages
|
|
from django.shortcuts import redirect
|
|
|
|
class ModuleAccessMixin(AccessMixin):
|
|
"""Verify that the current user has access to the module."""
|
|
module_name = None
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
if not request.user.is_authenticated:
|
|
return self.handle_no_permission()
|
|
|
|
if not request.user.has_module_access(self.module_name):
|
|
messages.error(request, f'You do not have access to the {self.module_name} module.')
|
|
return redirect('dashboard:home')
|
|
|
|
return super().dispatch(request, *args, **kwargs)
|
|
```
|
|
|
|
### 8. Template-level Permission Checking
|
|
|
|
```html
|
|
<!-- In templates, check permissions like this -->
|
|
{% if perms.inventory.add_product %}
|
|
<a href="{% url 'inventory:create_product' %}" class="btn btn-primary">
|
|
<i class="fas fa-plus"></i> Add Product
|
|
</a>
|
|
{% endif %}
|
|
|
|
<!-- Or check multiple permissions -->
|
|
{% if perms.inventory.view_product and perms.inventory.change_product %}
|
|
<!-- Show edit functionality -->
|
|
{% endif %}
|
|
```
|
|
|
|
### 9. Admin Interface Permissions
|
|
|
|
```python
|
|
# accounts/admin.py
|
|
|
|
from django.contrib import admin
|
|
from django.contrib.auth.admin import UserAdmin
|
|
from .models import User
|
|
|
|
@admin.register(User)
|
|
class CustomUserAdmin(UserAdmin):
|
|
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'is_active')
|
|
list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups')
|
|
fieldsets = UserAdmin.fieldsets + (
|
|
('Additional Info', {'fields': ('phone', 'department', 'position')}),
|
|
)
|
|
add_fieldsets = UserAdmin.add_fieldsets + (
|
|
('Additional Info', {'fields': ('phone', 'department', 'position')}),
|
|
)
|
|
```
|
|
|
|
### 10. Permission Checking in Templates
|
|
|
|
```html
|
|
<!-- Check if user has specific permissions -->
|
|
{% if user.is_superuser %}
|
|
<!-- Show admin-only features -->
|
|
{% endif %}
|
|
|
|
{% if perms.inventory.view_product %}
|
|
<!-- Show inventory features -->
|
|
{% endif %}
|
|
|
|
<!-- Check multiple permissions -->
|
|
{% if perms.purchasing.view_purchaseorder and perms.purchasing.add_purchaseorder %}
|
|
<!-- Show purchasing features -->
|
|
{% endif %}
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
### 11. Password Policies
|
|
```python
|
|
# settings.py
|
|
|
|
AUTH_PASSWORD_VALIDATORS = [
|
|
{
|
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
|
},
|
|
{
|
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
|
'OPTIONS': {
|
|
'min_length': 8,
|
|
}
|
|
},
|
|
{
|
|
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
|
},
|
|
{
|
|
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
|
},
|
|
]
|
|
```
|
|
|
|
### 12. Session Management
|
|
```python
|
|
# settings.py
|
|
|
|
SESSION_COOKIE_AGE = 3600 # 1 hour
|
|
SESSION_SAVE_EVERY_REQUEST = True
|
|
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
|
|
```
|
|
|
|
### 13. Login Attempt Protection
|
|
Using django-axes for login attempt tracking:
|
|
```python
|
|
# settings.py
|
|
|
|
INSTALLED_APPS = [
|
|
# ...
|
|
'axes',
|
|
]
|
|
|
|
MIDDLEWARE = [
|
|
# ...
|
|
'axes.middleware.AxesMiddleware',
|
|
]
|
|
|
|
AUTHENTICATION_BACKENDS = [
|
|
'axes.backends.AxesBackend',
|
|
'django.contrib.auth.backends.ModelBackend',
|
|
]
|
|
|
|
# Axes configuration
|
|
AXES_FAILURE_LIMIT = 5
|
|
AXES_COOLOFF_TIME = 1 # hours
|
|
AXES_LOCKOUT_TEMPLATE = 'accounts/locked_out.html'
|
|
```
|
|
|
|
This authentication and authorization system provides a robust security framework for the manufacturing application, ensuring that users can only access the modules and functionality they are authorized to use. |