mirror of
https://github.com/gmfricke/cmmc_audit.git
synced 2026-06-29 04:03:03 -06:00
174 lines
5.7 KiB
Python
174 lines
5.7 KiB
Python
from django.contrib.auth import get_user_model
|
|
|
|
|
|
def _get_model(app_label, model_name):
|
|
from django.apps import apps
|
|
|
|
return apps.get_model(app_label, model_name)
|
|
|
|
|
|
def _object_label(app_label, model_name, pk, formatter=None):
|
|
if pk in (None, ""):
|
|
return None
|
|
try:
|
|
obj = _get_model(app_label, model_name).objects.get(pk=pk)
|
|
except Exception:
|
|
return None
|
|
if formatter is not None:
|
|
return formatter(obj)
|
|
return str(obj)
|
|
|
|
|
|
def user_label(user):
|
|
full_name = user.get_full_name()
|
|
if full_name:
|
|
return f"{user.username} ({full_name})"
|
|
return user.username
|
|
|
|
|
|
def user_profile_label(user_profile):
|
|
try:
|
|
return user_label(user_profile.user)
|
|
except Exception:
|
|
return f"UserProfile id {user_profile.pk} (user not found)"
|
|
|
|
|
|
def user_profile_label_from_id(user_profile_id):
|
|
try:
|
|
user_profile = _get_model("user", "UserProfile").objects.select_related("user").get(pk=user_profile_id)
|
|
except Exception:
|
|
return f"UserProfile id {user_profile_id} (user not found)"
|
|
return user_profile_label(user_profile)
|
|
|
|
|
|
def _resource_allocation_prefix(resource_names):
|
|
names = [name for name in resource_names if name]
|
|
if not names:
|
|
return "Allocation"
|
|
if len(names) <= 2:
|
|
return f"{', '.join(names)} allocation"
|
|
return f"{', '.join(names[:2])} + {len(names) - 2} more allocation"
|
|
|
|
|
|
def allocation_label_from_parts(resource_names, project_reference):
|
|
return f"{_resource_allocation_prefix(resource_names)} for {project_reference}"
|
|
|
|
|
|
def project_label_from_id(project_id):
|
|
if project_id in (None, ""):
|
|
return "Project unknown"
|
|
try:
|
|
return project_label(_get_model("project", "Project").objects.get(pk=project_id))
|
|
except Exception:
|
|
return f"Project id {project_id} (not found)"
|
|
|
|
|
|
def allocation_label(allocation):
|
|
resources = list(allocation.resources.values_list("name", flat=True).order_by("name"))
|
|
try:
|
|
project_reference = project_label(allocation.project)
|
|
except Exception:
|
|
project_reference = project_label_from_id(getattr(allocation, "project_id", None))
|
|
return allocation_label_from_parts(resources, project_reference)
|
|
|
|
|
|
def allocation_change_label(allocation_change):
|
|
return f"change request for {allocation_label(allocation_change.allocation)}"
|
|
|
|
|
|
def project_user_label(project_user):
|
|
return f"{project_user.user.username} on {project_label(project_user.project)}"
|
|
|
|
|
|
def project_review_label(project_review):
|
|
return f"review for {project_label(project_review.project)}"
|
|
|
|
|
|
def project_label(project):
|
|
label = f"Project: {project.title}"
|
|
if getattr(project, "project_code", ""):
|
|
label = f"{label} (code {project.project_code})"
|
|
return label
|
|
|
|
|
|
def resolve_target_label(target_type, target_id):
|
|
formatter_map = {
|
|
"allocation.allocation": lambda obj: allocation_label(obj),
|
|
"allocation.allocationchangerequest": lambda obj: allocation_change_label(obj),
|
|
"auth.user": lambda obj: user_label(obj),
|
|
"user.userprofile": lambda obj: user_profile_label(obj),
|
|
"project.project": lambda obj: project_label(obj),
|
|
"project.projectuser": lambda obj: project_user_label(obj),
|
|
"project.projectreview": lambda obj: project_review_label(obj),
|
|
"resource.resource": lambda obj: obj.name,
|
|
}
|
|
if "." not in target_type:
|
|
return None
|
|
app_label, model_name = target_type.split(".", 1)
|
|
if target_type == "project.project":
|
|
return project_label_from_id(target_id)
|
|
return _object_label(app_label, model_name, target_id, formatter_map.get(target_type))
|
|
|
|
|
|
def _resolve_id(key, value):
|
|
if key in {"project_id", "project"}:
|
|
label = _object_label("project", "Project", value, lambda obj: project_label(obj))
|
|
elif key in {"user_id", "user"}:
|
|
label = _object_label("auth", "User", value, lambda obj: user_label(obj))
|
|
elif key in {"allocation_id", "allocation"}:
|
|
label = _object_label("allocation", "Allocation", value, lambda obj: allocation_label(obj))
|
|
elif key in {"allocation_change_request_id", "allocation_change_request"}:
|
|
label = _object_label(
|
|
"allocation",
|
|
"AllocationChangeRequest",
|
|
value,
|
|
lambda obj: allocation_change_label(obj),
|
|
)
|
|
elif key in {"resource_type_id", "resource_type"}:
|
|
label = _object_label("resource", "ResourceType", value)
|
|
elif key in {"parent_resource_id", "parent_resource"}:
|
|
label = _object_label("resource", "Resource", value, lambda obj: obj.name)
|
|
else:
|
|
label = None
|
|
|
|
if not label:
|
|
return value
|
|
return f"{label} (id {value})"
|
|
|
|
|
|
def _resolve_id_list(key, values):
|
|
if key == "resource_ids":
|
|
labels = []
|
|
for value in values:
|
|
label = _object_label("resource", "Resource", value, lambda obj: obj.name)
|
|
labels.append(f"{label} (id {value})" if label else value)
|
|
return labels
|
|
return values
|
|
|
|
|
|
def resolve_value_labels(values):
|
|
if not isinstance(values, dict):
|
|
return values
|
|
|
|
resolved = {}
|
|
for key, value in values.items():
|
|
if isinstance(value, list):
|
|
resolved[key] = _resolve_id_list(key, value)
|
|
elif key.endswith("_id") or key in {"project", "user", "allocation", "resource_type", "parent_resource"}:
|
|
resolved[key] = _resolve_id(key, value)
|
|
else:
|
|
resolved[key] = value
|
|
return resolved
|
|
|
|
|
|
def actor_label(actor):
|
|
if actor is None:
|
|
return "programmatic"
|
|
return user_label(actor)
|
|
|
|
|
|
def username_from_id(user_id):
|
|
try:
|
|
return user_label(get_user_model().objects.get(pk=user_id))
|
|
except Exception:
|
|
return str(user_id)
|