from docx import Document
from docx.shared import Pt, RGBColor, Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml import OxmlElement
from docx.oxml.ns import qn


def set_cell_bg(cell, color_hex: str):
    tc_pr = cell._tc.get_or_add_tcPr()
    shd = OxmlElement("w:shd")
    shd.set(qn("w:fill"), color_hex)
    tc_pr.append(shd)


def set_table_borders(table):
    tbl = table._tbl
    tbl_pr = tbl.tblPr
    borders = OxmlElement("w:tblBorders")
    for edge in ("top", "left", "bottom", "right", "insideH", "insideV"):
        elem = OxmlElement(f"w:{edge}")
        elem.set(qn("w:val"), "single")
        elem.set(qn("w:sz"), "6")
        elem.set(qn("w:space"), "0")
        elem.set(qn("w:color"), "D9DEE7")
        borders.append(elem)
    tbl_pr.append(borders)


doc = Document()
section = doc.sections[0]
section.top_margin = Inches(0.8)
section.bottom_margin = Inches(0.8)
section.left_margin = Inches(0.85)
section.right_margin = Inches(0.85)

# Base font
normal = doc.styles["Normal"]
normal.font.name = "Calibri"
normal.font.size = Pt(11)

# Cover
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
r = p.add_run("LAPORAN PENETRATION TEST")
r.bold = True
r.font.size = Pt(26)
r.font.color.rgb = RGBColor(21, 35, 66)

p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
r = p.add_run("Aplikasi RTIK (Laravel)")
r.font.size = Pt(16)
r.font.color.rgb = RGBColor(52, 73, 94)

doc.add_paragraph("")
meta = doc.add_table(rows=4, cols=2)
meta.style = "Table Grid"
set_table_borders(meta)
meta.columns[0].width = Inches(2.2)
meta.columns[1].width = Inches(4.2)
labels = ["Target", "Tanggal Uji", "Metode", "Penguji"]
vals = [
    r"C:\laragon\www\rtik",
    "28 April 2026",
    "Source Code Security Review (White-box, Non-intrusive)",
    "Tim Internal",
]
for i in range(4):
    meta.cell(i, 0).text = labels[i]
    meta.cell(i, 1).text = vals[i]
    set_cell_bg(meta.cell(i, 0), "EEF3FB")
    for c in (meta.cell(i, 0), meta.cell(i, 1)):
        for par in c.paragraphs:
            par.paragraph_format.space_after = Pt(4)

doc.add_page_break()

def h1(text):
    p = doc.add_paragraph()
    run = p.add_run(text)
    run.bold = True
    run.font.size = Pt(16)
    run.font.color.rgb = RGBColor(20, 45, 90)
    p.paragraph_format.space_before = Pt(8)
    p.paragraph_format.space_after = Pt(6)


def body(text):
    p = doc.add_paragraph(text)
    p.paragraph_format.space_after = Pt(6)
    p.paragraph_format.line_spacing = 1.2


h1("Ringkasan Eksekutif")
body(
    "Pengujian menemukan 1 temuan kritis, 1 tinggi, 1 menengah (sudah dimitigasi), "
    "dan 1 rendah/menengah. Prioritas utama adalah manajemen secret, hardening deployment, "
    "serta pengurangan log sensitif."
)

h1("Scope dan Metodologi")
for t in [
    "Review kode pada route/controller/provider utama.",
    "Fokus pada autentikasi, validasi input, upload/download file, serta konfigurasi deployment.",
    "Tidak mencakup uji destruktif dan stress test production.",
]:
    body("• " + t)

h1("Ringkasan Temuan")
tbl = doc.add_table(rows=1, cols=5)
tbl.style = "Table Grid"
set_table_borders(tbl)
headers = ["ID", "Severity", "Temuan", "Dampak", "Status"]
for i, h in enumerate(headers):
    cell = tbl.cell(0, i)
    cell.text = h
    set_cell_bg(cell, "1E3A8A")
    for run in cell.paragraphs[0].runs:
        run.bold = True
        run.font.color.rgb = RGBColor(255, 255, 255)

rows = [
    ("F-01", "Critical", "Hardcoded DB credential", "Risiko akses DB tidak sah", "Open"),
    ("F-02", "High", "Script operasional di root", "Info disclosure dan abuse operasional", "Open"),
    ("F-03", "Medium", "Brute-force login protection", "Credential stuffing/brute-force", "Mitigated"),
    ("F-04", "Low/Med", "Verbose logging upload", "Potensi bocor informasi internal", "Open"),
]
for row in rows:
    cells = tbl.add_row().cells
    for i, v in enumerate(row):
        cells[i].text = v
    sev = row[1]
    if sev == "Critical":
        set_cell_bg(cells[1], "FEE2E2")
    elif sev == "High":
        set_cell_bg(cells[1], "FFEDD5")
    elif sev == "Medium":
        set_cell_bg(cells[1], "FEF9C3")
    else:
        set_cell_bg(cells[1], "E0F2FE")

h1("Keamanan yang Sudah Diterapkan")
controls = [
    "Multi-guard authentication (admin dan anggota).",
    "Middleware akses berbasis peran: admin, pembina, wilayah, anggota.",
    "Session hardening: regenerate session saat login; invalidate + regenerate token saat logout.",
    "Validasi input request di endpoint utama.",
    "Password hashing menggunakan Hash::make / Hash::check.",
    "Validasi upload file (tipe, ekstensi, ukuran).",
    "Rate limiting login (5 request/menit per username+IP).",
    "Query parameterized via Eloquent/Query Builder.",
    "Proteksi CSRF bawaan Laravel untuk request state-changing.",
]
for c in controls:
    body("• " + c)

h1("Rekomendasi Prioritas (7 Hari)")
for t in [
    "Rotate credential database yang pernah hardcoded dan audit riwayat distribusi secret.",
    "Pindahkan/hapus script setup dari area publik, tambahkan pembatasan akses jika masih dibutuhkan.",
    "Kurangi logging sensitif di production (masking dan log-level policy).",
    "Lakukan retest setelah remediation untuk verifikasi penutupan temuan.",
]:
    body("1. " + t)

h1("Lampiran")
body("Patch yang sudah diterapkan saat assessment:")
body("• Tambah RateLimiter::for('login') di AppServiceProvider.")
body("• Terapkan middleware throttle:login pada route POST login admin dan anggota.")

output = r"C:\laragon\www\rtik\Laporan_Pentest_RTIK_Desain.docx"
doc.save(output)
print(output)

