Skip to content

Commit

Permalink
task/WI-204: Enhanced logging for Audit Trails (#1482)
Browse files Browse the repository at this point in the history
* enhance logging for audit trails

* include jobs post response in metrics log (#1483)

---------

Co-authored-by: Sal Tijerina <[email protected]>
  • Loading branch information
jarosenb and rstijerina authored Nov 6, 2024
1 parent 9274579 commit afc93ce
Show file tree
Hide file tree
Showing 4 changed files with 306 additions and 28 deletions.
223 changes: 223 additions & 0 deletions designsafe/apps/api/projects_v2/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@
)
from designsafe.apps.api.projects_v2.schema_models.base import FileObj
from designsafe.apps.api.decorators import tapis_jwt_login
from designsafe.apps.api.utils import get_client_ip


logger = logging.getLogger(__name__)
metrics = logging.getLogger("metrics")


def get_search_filter(query_string):
Expand All @@ -74,6 +76,18 @@ def get(self, request: HttpRequest):
# user = get_user_model().objects.get(username="ds_admin")
user = request.user

metrics.info(
"Projects",
extra={
"user": request.user.username,
"sessionId": getattr(request.session, "session_key", ""),
"operation": "projects.listing",
"agent": request.META.get("HTTP_USER_AGENT"),
"ip": get_client_ip(request),
"info": {},
},
)

if not request.user.is_authenticated:
raise ApiException("Unauthenticated user", status=401)

Expand All @@ -100,6 +114,18 @@ def post(self, request: HttpRequest):
metadata_value = req_body.get("value", {})
# Projects are initialized as type None

metrics.info(
"Projects",
extra={
"user": request.user.username,
"sessionId": getattr(request.session, "session_key", ""),
"operation": "projects.create",
"agent": request.META.get("HTTP_USER_AGENT"),
"ip": get_client_ip(request),
"info": {"body": req_body},
},
)

# increment project count
prj_number = increment_workspace_count()
# create metadata and graph
Expand All @@ -123,6 +149,19 @@ class ProjectInstanceView(BaseApiView):
def get(self, request: HttpRequest, project_id: str):
"""Return all project metadata for a project ID"""
user = request.user

metrics.info(
"Projects",
extra={
"user": request.user.username,
"sessionId": getattr(request.session, "session_key", ""),
"operation": "projects.detail",
"agent": request.META.get("HTTP_USER_AGENT"),
"ip": get_client_ip(request),
"info": {"project_id": project_id},
},
)

if not request.user.is_authenticated:
raise ApiException("Unauthenticated user", status=401)

Expand Down Expand Up @@ -163,6 +202,19 @@ def put(self, request: HttpRequest, project_id: str):

# Get the new value from the request data
req_body = json.loads(request.body)

metrics.info(
"Projects",
extra={
"user": request.user.username,
"sessionId": getattr(request.session, "session_key", ""),
"operation": "projects.change_project_type",
"agent": request.META.get("HTTP_USER_AGENT"),
"ip": get_client_ip(request),
"info": {"project_id": project, "body": req_body},
},
)

new_value = req_body.get("value", {})
sensitive_data_option = req_body.get("sensitiveData", False)
if sensitive_data_option:
Expand Down Expand Up @@ -200,6 +252,19 @@ def patch(self, request: HttpRequest, project_id: str):
) from exc

request_body = json.loads(request.body).get("patchMetadata", {})

metrics.info(
"Projects",
extra={
"user": request.user.username,
"sessionId": getattr(request.session, "session_key", ""),
"operation": "projects.patch_project",
"agent": request.META.get("HTTP_USER_AGENT"),
"ip": get_client_ip(request),
"info": {"project_id": project, "body": request_body},
},
)

prev_metadata = BaseProject.model_validate(project.value)
updated_project = patch_metadata(project.uuid, request_body)
updated_metadata = BaseProject.model_validate(updated_project.value)
Expand Down Expand Up @@ -231,6 +296,19 @@ def patch(self, request: HttpRequest, entity_uuid: str):
)

request_body = json.loads(request.body).get("patchMetadata", {})

metrics.info(
"Projects",
extra={
"user": request.user.username,
"sessionId": getattr(request.session, "session_key", ""),
"operation": "projects.patch_metadata",
"agent": request.META.get("HTTP_USER_AGENT"),
"ip": get_client_ip(request),
"info": {"entity_uuid": entity_uuid, "body": request_body},
},
)

logger.debug(request_body)
patch_metadata(entity_uuid, request_body)
return JsonResponse({"result": "OK"})
Expand All @@ -241,6 +319,18 @@ def delete(self, request: HttpRequest, entity_uuid: str):
if not request.user.is_authenticated:
raise ApiException("Unauthenticated user", status=401)

metrics.info(
"Projects",
extra={
"user": request.user.username,
"sessionId": getattr(request.session, "session_key", ""),
"operation": "projects.delete_entity",
"agent": request.META.get("HTTP_USER_AGENT"),
"ip": get_client_ip(request),
"info": {"entity_uuid": entity_uuid},
},
)

entity_meta = ProjectMetadata.objects.get(uuid=entity_uuid)
if user not in entity_meta.base_project.users.all():
raise ApiException(
Expand Down Expand Up @@ -268,6 +358,19 @@ def post(self, request: HttpRequest, project_id: str):
) from exc

req_body = json.loads(request.body)

metrics.info(
"Projects",
extra={
"user": request.user.username,
"sessionId": getattr(request.session, "session_key", ""),
"operation": "projects.create_entity",
"agent": request.META.get("HTTP_USER_AGENT"),
"ip": get_client_ip(request),
"info": {"project_id": project_id, "body": req_body},
},
)

value = req_body.get("value", {})
name = req_body.get("name", "")

Expand Down Expand Up @@ -315,6 +418,18 @@ def put(self, request: HttpRequest, project_id: str):
node_id = request_body.get("nodeId")
order = request_body.get("order")

metrics.info(
"Projects",
extra={
"user": request.user.username,
"sessionId": getattr(request.session, "session_key", ""),
"operation": "projects.reorder_entities",
"agent": request.META.get("HTTP_USER_AGENT"),
"ip": get_client_ip(request),
"info": {"project_id": project_id, "body": request_body},
},
)

if not node_id or order is None:
raise ApiException("Node ID and new order must be specified", status=400)

Expand Down Expand Up @@ -345,6 +460,22 @@ def post(self, request: HttpRequest, project_id, node_id):
user = request.user
entity_uuid = request_body.get("uuid")

metrics.info(
"Projects",
extra={
"user": request.user.username,
"sessionId": getattr(request.session, "session_key", ""),
"operation": "projects.delete_entity",
"agent": request.META.get("HTTP_USER_AGENT"),
"ip": get_client_ip(request),
"info": {
"project_id": project_id,
"node_id": node_id,
"body": request_body,
},
},
)

if not entity_uuid:
raise ApiException("Entity UUID must be provided", status=400)

Expand Down Expand Up @@ -372,6 +503,19 @@ def post(self, request: HttpRequest, project_id, node_id):
def delete(self, request: HttpRequest, project_id, node_id):
"""Remove a node from the project tree."""
user = request.user

metrics.info(
"Projects",
extra={
"user": request.user.username,
"sessionId": getattr(request.session, "session_key", ""),
"operation": "projects.remove_node",
"agent": request.META.get("HTTP_USER_AGENT"),
"ip": get_client_ip(request),
"info": {"project_id": project_id, "node_id": node_id},
},
)

if not request.user.is_authenticated:
raise ApiException("Unauthenticated user", status=401)

Expand Down Expand Up @@ -409,6 +553,22 @@ def patch(self, request: HttpRequest, project_id, entity_uuid):

user = request.user

metrics.info(
"Projects",
extra={
"user": request.user.username,
"sessionId": getattr(request.session, "session_key", ""),
"operation": "projects.patch_files",
"agent": request.META.get("HTTP_USER_AGENT"),
"ip": get_client_ip(request),
"info": {
"project_id": project_id,
"entity_uuid": entity_uuid,
"body": file_obj_data,
},
},
)

if not entity_uuid:
raise ApiException("Entity UUID must be provided", status=400)

Expand Down Expand Up @@ -451,6 +611,22 @@ def put(self, request: HttpRequest, project_id, entity_uuid):

user = request.user

metrics.info(
"Projects",
extra={
"user": request.user.username,
"sessionId": getattr(request.session, "session_key", ""),
"operation": "projects.put_files",
"agent": request.META.get("HTTP_USER_AGENT"),
"ip": get_client_ip(request),
"info": {
"project_id": project_id,
"entity_uuid": entity_uuid,
"body": file_obj_data,
},
},
)

if not entity_uuid:
raise ApiException("Entity UUID must be provided", status=400)

Expand Down Expand Up @@ -480,6 +656,22 @@ def delete(self, request: HttpRequest, project_id, entity_uuid, file_path):
"""Remove the association between a file and an entity."""
user = request.user

metrics.info(
"Projects",
extra={
"user": request.user.username,
"sessionId": getattr(request.session, "session_key", ""),
"operation": "projects.remove_file",
"agent": request.META.get("HTTP_USER_AGENT"),
"ip": get_client_ip(request),
"info": {
"project_id": project_id,
"entity_uuid": entity_uuid,
"file_path": file_path,
},
},
)

if not entity_uuid:
raise ApiException("Entity UUID must be provided", status=400)

Expand Down Expand Up @@ -515,6 +707,22 @@ def put(self, request: HttpRequest, project_id, entity_uuid, file_path):

user = request.user

metrics.info(
"Projects",
extra={
"user": request.user.username,
"sessionId": getattr(request.session, "session_key", ""),
"operation": "projects.set_file_tags",
"agent": request.META.get("HTTP_USER_AGENT"),
"ip": get_client_ip(request),
"info": {
"project_id": project_id,
"entity_uuid": entity_uuid,
"body": tag_names,
},
},
)

if not entity_uuid:
raise ApiException("Entity UUID must be provided", status=400)

Expand Down Expand Up @@ -547,6 +755,21 @@ class ProjectEntityValidateView(BaseApiView):
def post(self, request: HttpRequest, project_id):
"""validate a selection of entities to check publication-readiness."""
user = request.user

metrics.info(
"Projects",
extra={
"user": request.user.username,
"sessionId": getattr(request.session, "session_key", ""),
"operation": "projects.validate_entities",
"agent": request.META.get("HTTP_USER_AGENT"),
"ip": get_client_ip(request),
"info": {
"project_id": project_id,
},
},
)

if not request.user.is_authenticated:
raise ApiException("Unauthenticated user", status=401)

Expand Down
Loading

0 comments on commit afc93ce

Please sign in to comment.