11 KiB
11 KiB
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
# 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
# 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 dataadd_module: Can create new recordschange_module: Can edit existing recordsdelete_module: Can delete records
Module-specific Permissions:
User Management:
view_useradd_userchange_userdelete_userview_roleadd_rolechange_roledelete_role
Inventory Management:
view_productadd_productchange_productdelete_productview_inventorychange_inventoryview_stockmovementadd_stockmovement
Purchasing:
view_supplieradd_supplierchange_supplierdelete_supplierview_purchaseorderadd_purchaseorderchange_purchaseorderdelete_purchaseorderview_goodsreceiptadd_goodsreceipt
Sales:
view_customeradd_customerchange_customerdelete_customerview_salesorderadd_salesorderchange_salesorderdelete_salesorderview_deliveryadd_delivery
Manufacturing:
view_billofmaterialadd_billofmaterialchange_billofmaterialdelete_billofmaterialview_manufacturingorderadd_manufacturingorderchange_manufacturingorderdelete_manufacturingorder
Database Management:
view_databasebackupadd_databasebackupchange_databasebackupdelete_databasebackupcan_backup_databasecan_restore_databasecan_initialize_database
Reports:
view_reportgenerate_reportexport_report
Dashboard:
view_dashboardcustomize_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
# 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
# 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
# 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
# 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
# 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
<!-- 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
# 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
<!-- 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
# 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
# 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:
# 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.