215 lines
8.6 KiB
Python
215 lines
8.6 KiB
Python
from reportlab.lib import colors
|
|
from reportlab.lib.pagesizes import A4, landscape
|
|
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
|
from reportlab.lib.units import cm
|
|
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak
|
|
from reportlab.lib.enums import TA_CENTER, TA_LEFT
|
|
|
|
# 1. Configuração do Arquivo
|
|
pdf_filename = "Apresentacao_Executiva_FGCOOP.pdf"
|
|
doc = SimpleDocTemplate(pdf_filename, pagesize=landscape(A4),
|
|
rightMargin=1*cm, leftMargin=1*cm,
|
|
topMargin=3.5*cm, bottomMargin=1.5*cm)
|
|
|
|
# 2. Estilos
|
|
styles = getSampleStyleSheet()
|
|
|
|
# Estilo de Título do Slide
|
|
style_slide_title = ParagraphStyle(
|
|
'SlideTitle',
|
|
parent=styles['Heading1'],
|
|
fontSize=24,
|
|
textColor=colors.HexColor("#003366"), # Azul Corporativo
|
|
spaceAfter=20,
|
|
alignment=TA_LEFT
|
|
)
|
|
|
|
# Estilo de Corpo do Slide
|
|
style_body = ParagraphStyle(
|
|
'SlideBody',
|
|
parent=styles['Normal'],
|
|
fontSize=14,
|
|
leading=18,
|
|
spaceAfter=12,
|
|
textColor=colors.HexColor("#333333")
|
|
)
|
|
|
|
# Estilo de Bullet Point
|
|
style_bullet = ParagraphStyle(
|
|
'SlideBullet',
|
|
parent=style_body,
|
|
leftIndent=20,
|
|
bulletIndent=10,
|
|
firstLineIndent=0,
|
|
spaceAfter=8
|
|
)
|
|
|
|
# Estilo da Capa (Título Gigante)
|
|
style_cover_title = ParagraphStyle(
|
|
'CoverTitle',
|
|
parent=styles['Title'],
|
|
fontSize=36,
|
|
textColor=colors.white,
|
|
alignment=TA_CENTER,
|
|
spaceAfter=20,
|
|
leading=40
|
|
)
|
|
|
|
style_cover_sub = ParagraphStyle(
|
|
'CoverSub',
|
|
parent=styles['Normal'],
|
|
fontSize=18,
|
|
textColor=colors.lightgrey,
|
|
alignment=TA_CENTER
|
|
)
|
|
|
|
# 3. Funções de Layout (Background)
|
|
|
|
def draw_background(canvas, doc):
|
|
""" Fundo padrão dos slides (Barra azul no topo e rodapé) """
|
|
width, height = landscape(A4)
|
|
|
|
# Faixa Azul no Topo
|
|
canvas.saveState()
|
|
canvas.setFillColor(colors.HexColor("#003366"))
|
|
canvas.rect(0, height - 2.5*cm, width, 2.5*cm, fill=1, stroke=0)
|
|
|
|
# Texto do Header (na faixa azul)
|
|
canvas.setFont("Helvetica-Bold", 16)
|
|
canvas.setFillColor(colors.white)
|
|
canvas.drawString(1*cm, height - 1.8*cm, "CLOUD ESSENTIAL | Assessment de Segurança")
|
|
|
|
# Rodapé
|
|
canvas.setStrokeColor(colors.HexColor("#CCCCCC"))
|
|
canvas.setLineWidth(1)
|
|
canvas.line(1*cm, 1*cm, width-1*cm, 1*cm)
|
|
|
|
# Texto do Rodapé
|
|
canvas.setFont("Helvetica", 10)
|
|
canvas.setFillColor(colors.gray)
|
|
canvas.drawString(1*cm, 0.5*cm, "Cliente: FGCOOP")
|
|
page_num = canvas.getPageNumber()
|
|
canvas.drawRightString(width-1*cm, 0.5*cm, f"Slide {page_num}")
|
|
|
|
canvas.restoreState()
|
|
|
|
def draw_cover_background(canvas, doc):
|
|
""" Fundo exclusivo da capa (Azul Total) """
|
|
width, height = landscape(A4)
|
|
canvas.saveState()
|
|
|
|
# Fundo Azul Sólido
|
|
canvas.setFillColor(colors.HexColor("#003366"))
|
|
canvas.rect(0, 0, width, height, fill=1, stroke=0)
|
|
|
|
# Elemento decorativo (Círculo sutil)
|
|
canvas.setFillColor(colors.HexColor("#004080"))
|
|
canvas.circle(width/2, height/2, 12*cm, fill=1, stroke=0)
|
|
|
|
# Logo simulado no centro inferior
|
|
canvas.setFont("Helvetica-Bold", 14)
|
|
canvas.setFillColor(colors.white)
|
|
canvas.drawCentredString(width/2, 2*cm, "CLOUD ESSENTIAL TECH")
|
|
|
|
canvas.restoreState()
|
|
|
|
# 4. Construção do Conteúdo (Story)
|
|
story = []
|
|
|
|
# --- SLIDE 1: CAPA ---
|
|
story.append(Spacer(1, 4*cm))
|
|
story.append(Paragraph("Assessment de Infraestrutura<br/>& Segurança Microsoft", style_cover_title))
|
|
story.append(Spacer(1, 1.5*cm))
|
|
story.append(Paragraph("<b>Cliente:</b> FGCOOP", style_cover_sub))
|
|
story.append(Paragraph("Janeiro 2026", style_cover_sub))
|
|
story.append(PageBreak())
|
|
|
|
# --- SLIDE 2: RESUMO EXECUTIVO ---
|
|
story.append(Paragraph("Resumo Executivo", style_slide_title))
|
|
|
|
# Texto com destaque
|
|
story.append(Paragraph("<b>1. Visão Geral:</b> Avaliação técnica dos ambientes On-Premises, Azure e M365 realizada em 19/01/2026.", style_body))
|
|
story.append(Paragraph("<b>2. Ponto Forte (Cloud):</b> O ambiente possui um <b>Microsoft Secure Score de 82,13%</b>, superior à média de mercado (43%), indicando excelente maturidade em nuvem.", style_body))
|
|
story.append(Paragraph("<b>3. Ponto de Atenção (On-Prem):</b> A infraestrutura local (AD e Servidores) apresenta riscos críticos que podem comprometer a segurança da nuvem se não tratados.", style_body))
|
|
story.append(PageBreak())
|
|
|
|
# --- SLIDE 3: OTIMIZAÇÃO FINANCEIRA ---
|
|
story.append(Paragraph("Otimização de Custos (Licenciamento)", style_slide_title))
|
|
story.append(Paragraph("Identificamos licenças ativas sem uso ou subutilizadas. Ação imediata recomendada:", style_body))
|
|
|
|
data_cost = [
|
|
['Produto / Licença', 'Situação Identificada', 'Recomendação'],
|
|
['Microsoft 365 Business Basic', '44 Licenças não utilizadas', 'Cancelar ou realocar'],
|
|
['Power BI Premium', 'Subutilização de recursos', 'Downgrade para versão Pro'],
|
|
['Licenças F1', 'Baixo consumo', 'Revisar necessidade']
|
|
]
|
|
|
|
t_cost = Table(data_cost, colWidths=[7*cm, 8*cm, 8*cm])
|
|
t_cost.setStyle(TableStyle([
|
|
('BACKGROUND', (0,0), (-1,0), colors.HexColor("#004080")),
|
|
('TEXTCOLOR', (0,0), (-1,0), colors.white),
|
|
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
|
|
('BOTTOMPADDING', (0,0), (-1,0), 12),
|
|
('BACKGROUND', (0,1), (-1,-1), colors.whitesmoke),
|
|
('GRID', (0,0), (-1,-1), 1, colors.white),
|
|
('ALIGN', (0,0), (-1,-1), 'LEFT'),
|
|
('PADDING', (0,0), (-1,-1), 8),
|
|
]))
|
|
story.append(t_cost)
|
|
story.append(PageBreak())
|
|
|
|
# --- SLIDE 4: PONTOS FORTES ---
|
|
story.append(Paragraph("Destaques de Segurança (Pontos Fortes)", style_slide_title))
|
|
story.append(Paragraph("A FGCOOP já implementou controles avançados de identidade:", style_body))
|
|
|
|
story.append(Paragraph("• <b>Autenticação Passwordless:</b> Uso de FIDO2 e Windows Hello, eliminando vetores de ataque baseados em senha.", style_bullet))
|
|
story.append(Paragraph("• <b>Proteção de Identidade:</b> Bloqueio de senhas fracas no AD Local e proteção contra força bruta ativos.", style_bullet))
|
|
story.append(Paragraph("• <b>Acesso Condicional:</b> Políticas maduras que bloqueiam autenticação legada e validam o risco do login.", style_bullet))
|
|
story.append(PageBreak())
|
|
|
|
# --- SLIDE 5: RISCOS CRÍTICOS ---
|
|
story.append(Paragraph("Riscos Críticos Identificados", style_slide_title))
|
|
story.append(Paragraph("Ativos que requerem intervenção imediata para evitar incidentes:", style_body))
|
|
|
|
data_risk = [
|
|
['Ativo', 'Nível', 'Impacto Técnico'],
|
|
['Servidor SVM42000', 'CRÍTICO 🔴', 'Falha em Replicação, Sites e Certificados KDC'],
|
|
['SVMAZDC01 / SVMAWSAD1', 'ALTO 🟠', 'Instabilidade de conectividade e sub-redes'],
|
|
['Conta KRBTGT', 'ALTO 🟠', 'Senha nunca rotacionada (Risco de Golden Ticket)'],
|
|
['Protocolo NTLM', 'MÉDIO 🟡', 'Protocolo vulnerável ativo na rede interna']
|
|
]
|
|
|
|
t_risk = Table(data_risk, colWidths=[6*cm, 3*cm, 14*cm])
|
|
t_risk.setStyle(TableStyle([
|
|
('BACKGROUND', (0,0), (-1,0), colors.HexColor("#CC0000")),
|
|
('TEXTCOLOR', (0,0), (-1,0), colors.white),
|
|
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
|
|
('ALIGN', (0,0), (-1,-1), 'LEFT'),
|
|
('GRID', (0,0), (-1,-1), 0.5, colors.grey),
|
|
('PADDING', (0,0), (-1,-1), 10),
|
|
('BACKGROUND', (0,1), (-1,-1), colors.white),
|
|
]))
|
|
story.append(t_risk)
|
|
story.append(PageBreak())
|
|
|
|
# --- SLIDE 6: PLANO DE AÇÃO ---
|
|
story.append(Paragraph("Plano de Ação: Quick Wins (0-30 Dias)", style_slide_title))
|
|
story.append(Paragraph("Ações prioritárias de baixo esforço e alto impacto:", style_body))
|
|
|
|
story.append(Paragraph("1. <b>Saneamento do AD:</b> Rotacionar senha da conta KRBTGT e corrigir delegações Kerberos.", style_bullet))
|
|
story.append(Paragraph("2. <b>Hardening de Servidores:</b> Resolver erros de replicação no SVM42000 e habilitar assinatura LDAP.", style_bullet))
|
|
story.append(Paragraph("3. <b>Proteção de Endpoints:</b> Aplicar regras de redução de superfície de ataque (ASR) via Intune.", style_bullet))
|
|
story.append(Paragraph("4. <b>Limpeza Financeira:</b> Remover licenças Business Basic ociosas identificadas.", style_bullet))
|
|
story.append(PageBreak())
|
|
|
|
# --- SLIDE 7: CONCLUSÃO ---
|
|
story.append(Paragraph("Conclusão e Próximos Passos", style_slide_title))
|
|
|
|
story.append(Paragraph("A FGCOOP está bem posicionada na nuvem (Score 82%), mas possui um 'débito técnico' perigoso na infraestrutura base (On-Premises).", style_body))
|
|
story.append(Spacer(1, 1*cm))
|
|
story.append(Paragraph("<b>Recomendação Final:</b> Priorizar a estabilização dos servidores de identidade (SVM42000) antes de iniciar novos projetos de inovação.", style_body))
|
|
story.append(Spacer(1, 2*cm))
|
|
story.append(Paragraph("Documento gerado por Cloud Essential Tech", style_body))
|
|
|
|
# 5. Gerar PDF
|
|
doc.build(story, onFirstPage=draw_cover_background, onLaterPages=draw_background) |