135 lines
6.5 KiB
Python
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"},
|
|
},
|
|
)
|