larxius commited on
Commit
ca843ff
·
verified ·
1 Parent(s): 6cb9ff0

Update backend/utils/pdf_generator.py

Browse files
Files changed (1) hide show
  1. backend/utils/pdf_generator.py +24 -21
backend/utils/pdf_generator.py CHANGED
@@ -4,7 +4,7 @@ import hmac
4
  import secrets
5
  import base64
6
  import subprocess
7
- from typing import *
8
  import os
9
  import sys
10
  import re
@@ -26,12 +26,12 @@ import io
26
  import html
27
  from cryptography import x509
28
  from cryptography.hazmat.backends import default_backend
29
- from reportlab.lib import colors
30
- from reportlab.lib.pagesizes import letter
31
- from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
32
- from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak, Image, KeepTogether
33
- from reportlab.graphics.shapes import Drawing
34
- from reportlab.graphics.charts.barcharts import VerticalBarChart
35
 
36
 
37
  def get_ssl_info(url):
@@ -65,8 +65,8 @@ def get_ssl_info(url):
65
  }
66
 
67
  # Default getpeercert output
68
- issuer = dict([x[0] for x in cert.get('issuer', [])])
69
- subject = dict([x[0] for x in cert.get('subject', [])])
70
  issuer_str = issuer.get('organizationName', issuer.get('commonName', 'Unknown'))
71
  subject_str = subject.get('commonName', 'Unknown')
72
  not_after = cert.get('notAfter', 'Unknown')
@@ -100,7 +100,7 @@ class ReusableImage(Image):
100
  pass
101
  super().draw()
102
 
103
- def create_proportional_image(img_source, max_width=180, max_height=170, hAlign='CENTER'):
104
  """
105
  Creates a ReportLab ReusableImage object that strictly preserves original aspect ratio
106
  and survives multi-pass ReportLab builds.
@@ -131,8 +131,8 @@ def create_proportional_image(img_source, max_width=180, max_height=170, hAlign=
131
  except Exception:
132
  return ReusableImage(img_source, width=max_width, height=max_height, kind='proportional', hAlign=hAlign)
133
 
134
- from reportlab.pdfgen import canvas
135
- from reportlab.platypus import Flowable
136
 
137
  class PageTrackerCanvas(canvas.Canvas):
138
  def __init__(self, *args, **kwargs):
@@ -142,7 +142,7 @@ class PageTrackerCanvas(canvas.Canvas):
142
 
143
  def showPage(self):
144
  self.pages.append(dict(self.__dict__))
145
- self._startPage()
146
 
147
  def save(self):
148
  num_pages = len(self.pages)
@@ -163,7 +163,7 @@ class PageNumberRecorder(Flowable):
163
 
164
  def draw(self):
165
  if self.page_dict is not None:
166
- self.page_dict[self.key_name] = self.canv._pageNumber
167
 
168
  def generate_scan_pdf(scan, vulnerabilities):
169
  severity_order = {"Critical": 0, "High": 1, "Medium": 2, "Low": 3, "Informational": 4}
@@ -494,8 +494,8 @@ def generate_scan_pdf(scan, vulnerabilities):
494
  elements.append(Spacer(1, 10))
495
  elements.append(sev_t)
496
 
497
- from reportlab.graphics.charts.barcharts import VerticalBarChart
498
- from reportlab.graphics.shapes import Drawing
499
 
500
  color_map = {
501
  "Critical": colors.HexColor("#DC2626"),
@@ -732,6 +732,9 @@ def generate_scan_pdf(scan, vulnerabilities):
732
  cert = ssock.getpeercert()
733
  version = ssock.version() or "TLSv1.2"
734
 
 
 
 
735
  issuer_tuples = cert.get('issuer', ())
736
  issuer_parts = []
737
  for group in issuer_tuples:
@@ -965,7 +968,7 @@ def generate_scan_pdf(scan, vulnerabilities):
965
 
966
 
967
  # --- APPENDIX: REQUIRES MANUAL VERIFICATION (ONLY IF UNCONFIRMED FINDINGS EXIST) ---
968
- target_findings_list = vulnerabilities if 'vulnerabilities' in locals() and vulnerabilities is not None else (findings if 'findings' in locals() and findings is not None else getattr(scan, 'vulnerabilities', []))
969
 
970
  unconfirmed_findings = [
971
  v for v in (target_findings_list or [])
@@ -1128,7 +1131,7 @@ def generate_scan_pdf(scan, vulnerabilities):
1128
  "This report contains sensitive, proprietary vulnerability intelligence regarding the client organization's digital assets. Unauthorized distribution, public exposure, or reproduction of this document without prior written authorization from both the client organization and LarShield is strictly prohibited.")
1129
  ]
1130
 
1131
- content_flowables = [header_table, Spacer(1, 10)]
1132
 
1133
  card_cells = []
1134
  for idx, (title, body) in enumerate(disclaimer_items):
@@ -1159,8 +1162,8 @@ def generate_scan_pdf(scan, vulnerabilities):
1159
 
1160
  def header_footer_draw(canvas_obj, doc):
1161
  canvas_obj.saveState()
1162
- if canvas_obj._pageNumber > 2:
1163
- from reportlab.lib.utils import ImageReader
1164
  import pytz
1165
  from datetime import datetime
1166
 
@@ -1222,7 +1225,7 @@ def generate_scan_pdf(scan, vulnerabilities):
1222
  gen_time = datetime.now().strftime('%d-%b-%Y %H:%M')
1223
  canvas_obj.drawCentredString(letter[0] / 2.0, 30, f"{gen_time}")
1224
 
1225
- canvas_obj.drawRightString(letter[0] - 40, 30, f"Page {canvas_obj._pageNumber} of {total_pages[0]}")
1226
 
1227
  canvas_obj.restoreState()
1228
 
 
4
  import secrets
5
  import base64
6
  import subprocess
7
+ from typing import Any, cast, List
8
  import os
9
  import sys
10
  import re
 
26
  import html
27
  from cryptography import x509
28
  from cryptography.hazmat.backends import default_backend
29
+ from reportlab.lib import colors # type: ignore[import]
30
+ from reportlab.lib.pagesizes import letter # type: ignore[import]
31
+ from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle # type: ignore[import]
32
+ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak, Image, KeepTogether # type: ignore[import]
33
+ from reportlab.graphics.shapes import Drawing # type: ignore[import]
34
+ from reportlab.graphics.charts.barcharts import VerticalBarChart # type: ignore[import]
35
 
36
 
37
  def get_ssl_info(url):
 
65
  }
66
 
67
  # Default getpeercert output
68
+ issuer = {k: v for x in cert.get('issuer', []) for k, v in [x[0]]}
69
+ subject = {k: v for x in cert.get('subject', []) for k, v in [x[0]]}
70
  issuer_str = issuer.get('organizationName', issuer.get('commonName', 'Unknown'))
71
  subject_str = subject.get('commonName', 'Unknown')
72
  not_after = cert.get('notAfter', 'Unknown')
 
100
  pass
101
  super().draw()
102
 
103
+ def create_proportional_image(img_source, max_width=180, max_height=170, hAlign: Any = 'CENTER'):
104
  """
105
  Creates a ReportLab ReusableImage object that strictly preserves original aspect ratio
106
  and survives multi-pass ReportLab builds.
 
131
  except Exception:
132
  return ReusableImage(img_source, width=max_width, height=max_height, kind='proportional', hAlign=hAlign)
133
 
134
+ from reportlab.pdfgen import canvas # type: ignore[import]
135
+ from reportlab.platypus import Flowable # type: ignore[import]
136
 
137
  class PageTrackerCanvas(canvas.Canvas):
138
  def __init__(self, *args, **kwargs):
 
142
 
143
  def showPage(self):
144
  self.pages.append(dict(self.__dict__))
145
+ self._startPage() # type: ignore[attr-defined]
146
 
147
  def save(self):
148
  num_pages = len(self.pages)
 
163
 
164
  def draw(self):
165
  if self.page_dict is not None:
166
+ self.page_dict[self.key_name] = self.canv._pageNumber # type: ignore[attr-defined]
167
 
168
  def generate_scan_pdf(scan, vulnerabilities):
169
  severity_order = {"Critical": 0, "High": 1, "Medium": 2, "Low": 3, "Informational": 4}
 
494
  elements.append(Spacer(1, 10))
495
  elements.append(sev_t)
496
 
497
+ from reportlab.graphics.charts.barcharts import VerticalBarChart # type: ignore[import]
498
+ from reportlab.graphics.shapes import Drawing # type: ignore[import]
499
 
500
  color_map = {
501
  "Critical": colors.HexColor("#DC2626"),
 
732
  cert = ssock.getpeercert()
733
  version = ssock.version() or "TLSv1.2"
734
 
735
+ if cert is None:
736
+ raise ValueError("No certificate returned")
737
+
738
  issuer_tuples = cert.get('issuer', ())
739
  issuer_parts = []
740
  for group in issuer_tuples:
 
968
 
969
 
970
  # --- APPENDIX: REQUIRES MANUAL VERIFICATION (ONLY IF UNCONFIRMED FINDINGS EXIST) ---
971
+ target_findings_list = vulnerabilities if vulnerabilities is not None else getattr(scan, 'vulnerabilities', [])
972
 
973
  unconfirmed_findings = [
974
  v for v in (target_findings_list or [])
 
1131
  "This report contains sensitive, proprietary vulnerability intelligence regarding the client organization's digital assets. Unauthorized distribution, public exposure, or reproduction of this document without prior written authorization from both the client organization and LarShield is strictly prohibited.")
1132
  ]
1133
 
1134
+ content_flowables: List[Any] = [header_table, Spacer(1, 10)]
1135
 
1136
  card_cells = []
1137
  for idx, (title, body) in enumerate(disclaimer_items):
 
1162
 
1163
  def header_footer_draw(canvas_obj, doc):
1164
  canvas_obj.saveState()
1165
+ if canvas_obj._pageNumber > 2: # type: ignore[attr-defined]
1166
+ from reportlab.lib.utils import ImageReader # type: ignore[import]
1167
  import pytz
1168
  from datetime import datetime
1169
 
 
1225
  gen_time = datetime.now().strftime('%d-%b-%Y %H:%M')
1226
  canvas_obj.drawCentredString(letter[0] / 2.0, 30, f"{gen_time}")
1227
 
1228
+ canvas_obj.drawRightString(letter[0] - 40, 30, f"Page {canvas_obj._pageNumber} of {total_pages[0]}") # type: ignore[attr-defined]
1229
 
1230
  canvas_obj.restoreState()
1231