เพิ่ม RBAC

This commit is contained in:
Flook 2025-11-09 15:05:02 +07:00
parent 3e0594664a
commit 66b95f6475
2 changed files with 73 additions and 0 deletions

View File

@ -8,6 +8,9 @@ from ..serializers.ai_model_serializer import AiModelSerializer
from ..repositories.ai_model_repository import AiModelRepository
from ..services.ai_model_service import AiModelService, ConnectionError
from permissions.permission_classes import IsAdminOrManager
from rest_framework.permissions import IsAuthenticated
# Dependency Injection: สร้าง Instance ของ Repository และ Service
# สำหรับโปรเจกต์ขนาดเล็กสามารถทำแบบนี้ได้
repo = AiModelRepository()
@ -44,6 +47,20 @@ class AiModelRegistryViewSet(viewsets.ModelViewSet):
except Exception as e:
return Response({"detail": str(e)}, status=status.HTTP_400_BAD_REQUEST)
def get_permissions(self):
# การทำงานที่เกี่ยวข้องกับการเขียน/แก้ไข/ลบ ถือเป็นงาน Admin/Manager
if self.action in ['create', 'update', 'partial_update', 'destroy', 'set_status']:
# จำกัดสิทธิ์ ต้องเป็น Admin หรือ Manager เท่านั้น
return [IsAdminOrManager()]
# การทำงานที่เกี่ยวข้องกับการอ่านข้อมูล (List, Retrieve, Test Connection)
# ถือเป็นงานสำหรับผู้ใช้งานที่ล็อกอินแล้ว (Viewer ขึ้นไป)
elif self.action in ['list', 'retrieve', 'test_connection']:
return [IsAuthenticated()]
# Default สำหรับเมธอดอื่น ๆ หรือ Custom Action ที่ไม่ได้ระบุ
return [IsAuthenticated()]
# -----------------------------------------------
# Custom Action: ทดสอบการเชื่อมต่อ
# -----------------------------------------------

View File

@ -0,0 +1,56 @@
from rest_framework import permissions
from rest_framework.exceptions import PermissionDenied
# ----------------------------------------------------
# Base Class เพื่อใช้ Logic การตรวจสอบสิทธิ์ร่วมกัน
# ----------------------------------------------------
class BaseRolePermission(permissions.BasePermission):
"""
Base class สำหรบตรวจสอบสทธตาม is_superuser และ is_staff
"""
def is_admin(self, user):
return user.is_authenticated and user.is_superuser
def is_manager(self, user):
# ผู้จัดการคือ is_staff แต่ไม่ใช่ superuser
return user.is_authenticated and user.is_staff and not user.is_superuser
# หรือเพิ่มฟังก์ชัน is_model_owner(user) ถ้าจำเป็น
# ถ้าใช้ฟิลด์ 'role' ที่คุณเพิ่มใน Serializer ควรใช้:
# return user.is_authenticated and getattr(user, 'role', '').upper() == 'ADMIN'
# ----------------------------------------------------
# 1. Permission: อนุญาตเฉพาะ Admin เท่านั้น
# ----------------------------------------------------
class IsAdmin(BaseRolePermission):
message = "คุณไม่มีสิทธิ์เข้าถึงหน้านี้ (Admin Required)."
def has_permission(self, request, view):
# Admin คือ is_superuser
return self.is_admin(request.user)
# ----------------------------------------------------
# 2. Permission: อนุญาตเฉพาะ Admin หรือ Manager เท่านั้น
# ----------------------------------------------------
class IsAdminOrManager(BaseRolePermission):
message = "คุณต้องมีสิทธิ์ Admin หรือ Manager."
def has_permission(self, request, view):
# Admin หรือ Manager (is_staff)
return self.is_admin(request.user) or self.is_manager(request.user)
# ----------------------------------------------------
# 3. Permission: อนุญาตเฉพาะผู้ใช้ที่ผ่านการยืนยันตัวตนแล้ว (IsAuthenticated)
# และเป็น Viewer ขึ้นไป
# ----------------------------------------------------
# ไม่จำเป็นต้องสร้างคลาสนี้ถ้าใช้ DRF's IsAuthenticated โดยตรง
# แต่ถ้าต้องการเพิ่ม Logic อื่นๆ ในอนาคต ควรใช้คลาสนี้
class IsAuthenticatedViewer(permissions.BasePermission):
message = "คุณต้องเข้าสู่ระบบก่อน"
def has_permission(self, request, view):
return request.user.is_authenticated