116 lines
4.1 KiB
Python
116 lines
4.1 KiB
Python
import threading
|
|
|
|
from django.shortcuts import get_object_or_404
|
|
|
|
from coldfront.core.project.models import Project, ProjectReview
|
|
|
|
from .models import AuditEvent
|
|
from .resolvers import project_label, project_review_label
|
|
from .utils import log_event
|
|
|
|
|
|
PATCH_MARKER = "_carc_audit_project_review_patch_installed"
|
|
_state = threading.local()
|
|
|
|
|
|
def _suppressed_project_review_ids():
|
|
ids = getattr(_state, "suppressed_project_review_ids", None)
|
|
if ids is None:
|
|
ids = set()
|
|
_state.suppressed_project_review_ids = ids
|
|
return ids
|
|
|
|
|
|
def is_project_review_status_suppressed(project_review_pk):
|
|
return project_review_pk in _suppressed_project_review_ids()
|
|
|
|
|
|
def _status_name(project_review):
|
|
return getattr(project_review.status, "name", None)
|
|
|
|
|
|
def _review_values(project_review):
|
|
return {
|
|
"project_id": project_review.project_id,
|
|
"status": _status_name(project_review),
|
|
"reason_for_not_updating_project": project_review.reason_for_not_updating_project or "",
|
|
}
|
|
|
|
|
|
def install_project_review_audit_patch():
|
|
from coldfront.core.project import views as project_views
|
|
|
|
if getattr(project_views, PATCH_MARKER, False):
|
|
return
|
|
|
|
original_review_post = project_views.ProjectReviewView.post
|
|
original_complete_get = project_views.ProjectReviewCompleteView.get
|
|
|
|
def review_post(self, request, *args, **kwargs):
|
|
project = get_object_or_404(Project, pk=self.kwargs.get("pk"))
|
|
before_pk = (
|
|
ProjectReview.objects.filter(project=project)
|
|
.order_by("-pk")
|
|
.values_list("pk", flat=True)
|
|
.first()
|
|
)
|
|
|
|
response = original_review_post(self, request, *args, **kwargs)
|
|
|
|
project_review = (
|
|
ProjectReview.objects.filter(project=project)
|
|
.select_related("status", "project")
|
|
.order_by("-pk")
|
|
.first()
|
|
)
|
|
if project_review and project_review.pk != before_pk:
|
|
log_event(
|
|
AuditEvent.Action.PROJECT_REVIEW_SUBMITTED,
|
|
project_review,
|
|
new_values=_review_values(project_review),
|
|
message=(
|
|
f"Project review submitted for {project_label(project_review.project)} "
|
|
f"with status {_status_name(project_review)}"
|
|
),
|
|
actor=getattr(request, "user", None),
|
|
request=request,
|
|
source=AuditEvent.Source.COLDFRONT_WORKFLOW,
|
|
target_repr=project_review_label(project_review),
|
|
)
|
|
|
|
return response
|
|
|
|
def complete_get(self, request, project_review_pk):
|
|
project_review = get_object_or_404(
|
|
ProjectReview.objects.select_related("status", "project"),
|
|
pk=project_review_pk,
|
|
)
|
|
old_status = _status_name(project_review)
|
|
suppressed_ids = _suppressed_project_review_ids()
|
|
suppressed_ids.add(project_review_pk)
|
|
try:
|
|
response = original_complete_get(self, request, project_review_pk)
|
|
finally:
|
|
suppressed_ids.discard(project_review_pk)
|
|
|
|
project_review.refresh_from_db()
|
|
project_review = ProjectReview.objects.select_related("status", "project").get(pk=project_review.pk)
|
|
new_status = _status_name(project_review)
|
|
if old_status != new_status and new_status == "Completed":
|
|
log_event(
|
|
AuditEvent.Action.PROJECT_REVIEW_COMPLETED,
|
|
project_review,
|
|
old_values={"status": old_status, "project_id": project_review.project_id},
|
|
new_values={"status": new_status, "project_id": project_review.project_id},
|
|
message=f"Project review completed for {project_label(project_review.project)}",
|
|
actor=getattr(request, "user", None),
|
|
request=request,
|
|
source=AuditEvent.Source.COLDFRONT_WORKFLOW,
|
|
target_repr=project_review_label(project_review),
|
|
)
|
|
|
|
return response
|
|
|
|
project_views.ProjectReviewView.post = review_post
|
|
project_views.ProjectReviewCompleteView.get = complete_get
|
|
setattr(project_views, PATCH_MARKER, True)
|