fix(jira,evidence,tempo,settings): 4-issue fix batch
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled
Jira — PoC custom field: - Add customfield_10309 (Proof of Concept) to issue fields when creating test tickets so the attack procedure appears in the dedicated Jira field Tempo — blue team exclusion: - Remove blue_team_evaluation from _TEMPO_ACTIVITY_TYPES; blue team time is tracked internally (worklogs) for SLA but never sent to Tempo since blue team has no Jira access Evidence — uploaded_at NULL fix: - Set uploaded_at=datetime.utcnow() explicitly in upload_evidence router; the DB column has no server default so it was saving as NULL Evidence — presigned URL browser access: - Add MINIO_PUBLIC_ENDPOINT setting (config.py, docker-compose.prod.yml) - storage.py uses a dedicated _public_client for presigned URL generation so browsers receive URLs with the publicly accessible hostname instead of the internal Docker service name (minio:9000) - Expose MinIO port 9000 in docker-compose.prod.yml Evidence — Jira attachment: - After upload to MinIO, call jira.add_attachment() to attach the file to the linked Jira ticket (non-fatal; errors are logged and swallowed) Settings — hide Jira/Tempo from blue team: - ProfileSection checks user role; blue_lead and blue_tech do not see the Jira Integration or Tempo Integration personal settings sections Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,7 @@ Access Control
|
||||
import hashlib
|
||||
import os
|
||||
import uuid as _uuid
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, File, Form, Query, Request, UploadFile, status
|
||||
@@ -119,6 +120,7 @@ async def upload_evidence(
|
||||
file_path=key,
|
||||
sha256_hash=sha256,
|
||||
uploaded_by=current_user.id,
|
||||
uploaded_at=datetime.utcnow(), # set explicitly — DB column has no server default
|
||||
team=team,
|
||||
notes=notes,
|
||||
)
|
||||
@@ -140,9 +142,40 @@ async def upload_evidence(
|
||||
uow.commit()
|
||||
db.refresh(evidence)
|
||||
|
||||
# 7. Attach to Jira ticket if one exists (non-fatal)
|
||||
_attach_evidence_to_jira(db, test_id, content, safe_name, current_user)
|
||||
|
||||
return _evidence_to_out(evidence)
|
||||
|
||||
|
||||
def _attach_evidence_to_jira(
|
||||
db,
|
||||
test_id: _uuid.UUID,
|
||||
content: bytes,
|
||||
file_name: str,
|
||||
actor,
|
||||
) -> None:
|
||||
"""Attach uploaded evidence to the linked Jira ticket (non-fatal)."""
|
||||
try:
|
||||
from app.services.jira_service import get_test_jira_key, get_user_jira_client, has_jira_configured
|
||||
if not has_jira_configured(actor, db):
|
||||
return
|
||||
issue_key = get_test_jira_key(db, test_id)
|
||||
if not issue_key:
|
||||
return
|
||||
jira = get_user_jira_client(actor, db)
|
||||
jira.add_attachment(issue_key, filename=file_name, content=content)
|
||||
import logging
|
||||
logging.getLogger(__name__).info(
|
||||
"Attached evidence '%s' to Jira ticket %s", file_name, issue_key
|
||||
)
|
||||
except Exception as exc:
|
||||
import logging
|
||||
logging.getLogger(__name__).warning(
|
||||
"Failed to attach evidence '%s' to Jira: %s", file_name, exc, exc_info=True
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# GET /tests/{test_id}/evidence — list (with optional team filter)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user