gateway/modules/datamodels/datamodelRbac.py
2025-12-07 23:51:05 +01:00

135 lines
6.5 KiB
Python

"""RBAC models: AccessRule, AccessRuleContext, Role."""
import uuid
from typing import Optional, Dict
from enum import Enum
from pydantic import BaseModel, Field
from modules.shared.attributeUtils import registerModelLabels
from modules.datamodels.datamodelUam import AccessLevel
class AccessRuleContext(str, Enum):
"""Context type enumeration"""
DATA = "DATA" # Database tables and fields
UI = "UI" # UI elements and features
RESOURCE = "RESOURCE" # System resources (AI models, actions, etc.)
class Role(BaseModel):
"""Data model for RBAC roles"""
id: str = Field(
default_factory=lambda: str(uuid.uuid4()),
description="Unique ID of the role",
json_schema_extra={"frontend_type": "text", "frontend_readonly": True, "frontend_required": False}
)
roleLabel: str = Field(
description="Unique role label identifier (e.g., 'admin', 'user', 'viewer')",
json_schema_extra={"frontend_type": "text", "frontend_readonly": False, "frontend_required": True}
)
description: Dict[str, str] = Field(
description="Role description in multiple languages",
json_schema_extra={"frontend_type": "object", "frontend_readonly": False, "frontend_required": True}
)
isSystemRole: bool = Field(
False,
description="Whether this is a system role that cannot be deleted",
json_schema_extra={"frontend_type": "checkbox", "frontend_readonly": True, "frontend_required": False}
)
registerModelLabels(
"Role",
{"en": "Role", "fr": "Rôle"},
{
"id": {"en": "ID", "fr": "ID"},
"roleLabel": {"en": "Role Label", "fr": "Label du rôle"},
"description": {"en": "Description", "fr": "Description"},
"isSystemRole": {"en": "System Role", "fr": "Rôle système"},
},
)
class AccessRule(BaseModel):
"""Data model for access control rules"""
id: str = Field(
default_factory=lambda: str(uuid.uuid4()),
description="Unique ID of the access rule",
json_schema_extra={"frontend_type": "text", "frontend_readonly": True, "frontend_required": False}
)
roleLabel: str = Field(
description="Role label this rule applies to",
json_schema_extra={"frontend_type": "select", "frontend_readonly": False, "frontend_required": True, "frontend_options": "user.role"}
)
context: AccessRuleContext = Field(
description="Context type: DATA (database), UI (interface), RESOURCE (system resources)",
json_schema_extra={"frontend_type": "select", "frontend_readonly": False, "frontend_required": True, "frontend_options": [
{"value": "DATA", "label": {"en": "Data", "fr": "Données"}},
{"value": "UI", "label": {"en": "UI", "fr": "Interface"}},
{"value": "RESOURCE", "label": {"en": "Resource", "fr": "Ressource"}}
]}
)
item: Optional[str] = Field(
None,
description="Item identifier (null = all items in context). Format: DATA: '<table>' or '<table>.<field>', UI: cascading string (e.g., 'playground.voice.settings'), RESOURCE: cascading string (e.g., 'ai.model.anthropic')",
json_schema_extra={"frontend_type": "text", "frontend_readonly": False, "frontend_required": False}
)
view: bool = Field(
False,
description="View permission: if true, item is visible/enabled. Only objects with view=true are shown.",
json_schema_extra={"frontend_type": "checkbox", "frontend_readonly": False, "frontend_required": True}
)
read: Optional[AccessLevel] = Field(
None,
description="Read permission level (only for DATA context)",
json_schema_extra={"frontend_type": "select", "frontend_readonly": False, "frontend_required": False, "frontend_options": [
{"value": "a", "label": {"en": "All Records", "fr": "Tous les enregistrements"}},
{"value": "m", "label": {"en": "My Records", "fr": "Mes enregistrements"}},
{"value": "g", "label": {"en": "Group Records", "fr": "Enregistrements du groupe"}},
{"value": "n", "label": {"en": "No Access", "fr": "Aucun accès"}}
]}
)
create: Optional[AccessLevel] = Field(
None,
description="Create permission level (only for DATA context)",
json_schema_extra={"frontend_type": "select", "frontend_readonly": False, "frontend_required": False, "frontend_options": [
{"value": "a", "label": {"en": "All Records", "fr": "Tous les enregistrements"}},
{"value": "m", "label": {"en": "My Records", "fr": "Mes enregistrements"}},
{"value": "g", "label": {"en": "Group Records", "fr": "Enregistrements du groupe"}},
{"value": "n", "label": {"en": "No Access", "fr": "Aucun accès"}}
]}
)
update: Optional[AccessLevel] = Field(
None,
description="Update permission level (only for DATA context)",
json_schema_extra={"frontend_type": "select", "frontend_readonly": False, "frontend_required": False, "frontend_options": [
{"value": "a", "label": {"en": "All Records", "fr": "Tous les enregistrements"}},
{"value": "m", "label": {"en": "My Records", "fr": "Mes enregistrements"}},
{"value": "g", "label": {"en": "Group Records", "fr": "Enregistrements du groupe"}},
{"value": "n", "label": {"en": "No Access", "fr": "Aucun accès"}}
]}
)
delete: Optional[AccessLevel] = Field(
None,
description="Delete permission level (only for DATA context)",
json_schema_extra={"frontend_type": "select", "frontend_readonly": False, "frontend_required": False, "frontend_options": [
{"value": "a", "label": {"en": "All Records", "fr": "Tous les enregistrements"}},
{"value": "m", "label": {"en": "My Records", "fr": "Mes enregistrements"}},
{"value": "g", "label": {"en": "Group Records", "fr": "Enregistrements du groupe"}},
{"value": "n", "label": {"en": "No Access", "fr": "Aucun accès"}}
]}
)
registerModelLabels(
"AccessRule",
{"en": "Access Rule", "fr": "Règle d'accès"},
{
"id": {"en": "ID", "fr": "ID"},
"roleLabel": {"en": "Role Label", "fr": "Label du rôle"},
"context": {"en": "Context", "fr": "Contexte"},
"item": {"en": "Item", "fr": "Élément"},
"view": {"en": "View", "fr": "Vue"},
"read": {"en": "Read", "fr": "Lecture"},
"create": {"en": "Create", "fr": "Créer"},
"update": {"en": "Update", "fr": "Mettre à jour"},
"delete": {"en": "Delete", "fr": "Supprimer"},
},
)