mirror of
https://github.com/FunnyWolf/agentic-soc-platform.git
synced 2026-08-22 13:12:56 +02:00
114 lines
4.2 KiB
Python
114 lines
4.2 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Iterable
|
|
|
|
from django.apps import apps
|
|
from django.db import models
|
|
from django.utils.module_loading import import_string
|
|
|
|
from apps.accounts.permissions import is_admin_user
|
|
|
|
SENSITIVE_FIELD_DENYLIST = {"password", "is_staff", "is_superuser", "groups", "user_permissions"}
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ResourceConfig:
|
|
key: str
|
|
label: str
|
|
model_label: str
|
|
endpoint: str
|
|
viewset_path: str
|
|
admin_only: bool = False
|
|
|
|
|
|
RESOURCE_CONFIGS: tuple[ResourceConfig, ...] = (
|
|
ResourceConfig("cases", "Cases", "cases.Case", "/cases/", "apps.cases.views.CaseViewSet"),
|
|
ResourceConfig("alerts", "Alerts", "alerts.Alert", "/alerts/", "apps.alerts.views.AlertViewSet"),
|
|
ResourceConfig("artifacts", "Artifacts", "artifacts.Artifact", "/artifacts/", "apps.artifacts.views.ArtifactViewSet"),
|
|
ResourceConfig("enrichments", "Enrichments", "enrichments.Enrichment", "/enrichments/", "apps.enrichments.views.EnrichmentViewSet"),
|
|
ResourceConfig("playbooks", "Playbooks", "playbooks.Playbook", "/playbooks/", "apps.playbooks.views.PlaybookViewSet"),
|
|
ResourceConfig("knowledge", "Knowledge", "knowledge.Knowledge", "/knowledge/", "apps.knowledge.views.KnowledgeViewSet"),
|
|
ResourceConfig("users", "Users", "accounts.User", "/auth/users/", "apps.accounts.views.UserViewSet", admin_only=True),
|
|
)
|
|
|
|
|
|
def _choices_for_field(field: models.Field) -> list[dict[str, str]]:
|
|
return [{"label": str(label), "value": str(value)} for value, label in field.choices]
|
|
|
|
|
|
def _viewset_options(viewset: type) -> dict[str, list[str]]:
|
|
return {
|
|
"search": list(getattr(viewset, "search_fields", ()) or ()),
|
|
"filters": list(getattr(viewset, "filterset_fields", ()) or ()),
|
|
}
|
|
|
|
|
|
def _field_metadata(model: type[models.Model]) -> dict[str, dict[str, str | bool]]:
|
|
result: dict[str, dict[str, str | bool]] = {}
|
|
for field in model._meta.get_fields():
|
|
if field.name in SENSITIVE_FIELD_DENYLIST:
|
|
continue
|
|
if not getattr(field, "concrete", False) and not getattr(field, "many_to_many", False):
|
|
continue
|
|
result[field.name] = {
|
|
"label": getattr(field, "verbose_name", field.name).replace("_", " ").title(),
|
|
"type": field.__class__.__name__,
|
|
"has_choices": bool(getattr(field, "choices", None)),
|
|
"help_text": str(getattr(field, "help_text", "") or ""),
|
|
}
|
|
return result
|
|
|
|
|
|
def _ordering_fields(viewset: type, model: type[models.Model]) -> list[str]:
|
|
ordering_fields = getattr(viewset, "ordering_fields", None)
|
|
if ordering_fields:
|
|
return list(ordering_fields)
|
|
return [
|
|
field.name
|
|
for field in model._meta.concrete_fields
|
|
if field.name not in SENSITIVE_FIELD_DENYLIST
|
|
]
|
|
|
|
|
|
def _resource_visible(config: ResourceConfig, user: object | None) -> bool:
|
|
if not config.admin_only:
|
|
return True
|
|
return is_admin_user(user)
|
|
|
|
|
|
def build_resource_metadata(
|
|
user: object | None = None,
|
|
configs: Iterable[ResourceConfig] = RESOURCE_CONFIGS,
|
|
) -> dict[str, dict[str, object]]:
|
|
resources: dict[str, dict[str, object]] = {}
|
|
for config in configs:
|
|
if not _resource_visible(config, user):
|
|
continue
|
|
|
|
model = apps.get_model(config.model_label)
|
|
viewset = import_string(config.viewset_path)
|
|
viewset_options = _viewset_options(viewset)
|
|
ordering = _ordering_fields(viewset, model)
|
|
fields = _field_metadata(model)
|
|
choices: dict[str, list[dict[str, str]]] = {}
|
|
for filter_name in viewset_options["filters"]:
|
|
field_name = filter_name.split("__", 1)[0]
|
|
try:
|
|
field = model._meta.get_field(field_name)
|
|
except Exception:
|
|
continue
|
|
if getattr(field, "choices", None):
|
|
choices[filter_name] = _choices_for_field(field)
|
|
|
|
resources[config.key] = {
|
|
"label": config.label,
|
|
"endpoint": config.endpoint,
|
|
"fields": fields,
|
|
"choices": choices,
|
|
"search": viewset_options["search"],
|
|
"filters": viewset_options["filters"],
|
|
"ordering": ordering,
|
|
}
|
|
return resources
|