Skip to content

Commit 4693beb

Browse files
authored
Doug/update comment template (#79)
* Changed Dependency Overview to new template * Updated the Security Issue comment to the new template
1 parent e8336f7 commit 4693beb

File tree

6 files changed

+251
-53
lines changed

6 files changed

+251
-53
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
66

77
[project]
88
name = "socketsecurity"
9-
version = "2.0.52"
9+
version = "2.0.54"
1010
requires-python = ">= 3.10"
1111
license = {"file" = "LICENSE"}
1212
dependencies = [

socketsecurity/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
__author__ = 'socket.dev'
2-
__version__ = '2.0.52'
2+
__version__ = '2.0.54'

socketsecurity/core/__init__.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
FullScan,
2222
Issue,
2323
Package,
24-
Purl,
24+
Purl
2525
)
2626
from socketsecurity.core.exceptions import APIResourceNotFound
2727
from socketsecurity.core.licenses import Licenses
@@ -644,7 +644,7 @@ def create_diff_report(
644644
seen_removed_packages = set()
645645

646646
for package_id, package in added_packages.items():
647-
purl = Core.create_purl(package_id, added_packages)
647+
purl = self.create_purl(package_id, added_packages)
648648
base_purl = f"{purl.ecosystem}/{purl.name}@{purl.version}"
649649

650650
if (not direct_only or package.direct) and base_purl not in seen_new_packages:
@@ -658,7 +658,7 @@ def create_diff_report(
658658
)
659659

660660
for package_id, package in removed_packages.items():
661-
purl = Core.create_purl(package_id, removed_packages)
661+
purl = self.create_purl(package_id, removed_packages)
662662
base_purl = f"{purl.ecosystem}/{purl.name}@{purl.version}"
663663

664664
if (not direct_only or package.direct) and base_purl not in seen_removed_packages:
@@ -682,8 +682,13 @@ def create_diff_report(
682682

683683
return diff
684684

685-
@staticmethod
686-
def create_purl(package_id: str, packages: dict[str, Package]) -> Purl:
685+
def get_all_scores(self, packages: dict[str, Package]) -> dict[str, Package]:
686+
components = []
687+
for package_id in packages:
688+
package = packages[package_id]
689+
return packages
690+
691+
def create_purl(self, package_id: str, packages: dict[str, Package]) -> Purl:
687692
"""
688693
Creates the extended PURL data for package identification and tracking.
689694
@@ -707,7 +712,8 @@ def create_purl(package_id: str, packages: dict[str, Package]) -> Purl:
707712
size=package.size,
708713
transitives=package.transitives,
709714
url=package.url,
710-
purl=package.purl
715+
purl=package.purl,
716+
scores=package.score
711717
)
712718
return purl
713719

socketsecurity/core/classes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,6 @@ def __init__(self, **kwargs):
370370
def __str__(self):
371371
return json.dumps(self.__dict__)
372372

373-
374373
class Purl:
375374
"""
376375
Represents a Package URL (PURL) with extended metadata.
@@ -392,6 +391,7 @@ class Purl:
392391
author_url: str
393392
url: str
394393
purl: str
394+
scores: dict[str, int]
395395

396396
def __init__(self, **kwargs):
397397
if kwargs:

socketsecurity/core/messages.py

Lines changed: 130 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -302,26 +302,95 @@ def create_security_comment_json(diff: Diff) -> dict:
302302
@staticmethod
303303
def security_comment_template(diff: Diff) -> str:
304304
"""
305-
Creates the security comment template
306-
:param diff: Diff - Diff report with the data needed for the template
307-
:return:
305+
Generates the security comment template in the new required format.
306+
Dynamically determines placement of the alerts table if markers like `<!-- start-socket-alerts-table -->` are used.
307+
308+
:param diff: Diff - Contains the detected vulnerabilities and warnings.
309+
:return: str - The formatted Markdown/HTML string.
308310
"""
309-
md = MdUtils(file_name="markdown_security_temp.md")
310-
md.new_line("<!-- socket-security-comment-actions -->")
311-
md.new_header(level=1, title="Socket Security: Issues Report")
312-
md.new_line("Potential security issues detected. Learn more about [socket.dev](https://socket.dev)")
313-
md.new_line("To accept the risk, merge this PR and you will not be notified again.")
314-
md.new_line()
315-
md.new_line("<!-- start-socket-alerts-table -->")
316-
md, ignore_commands, next_steps = Messages.create_security_alert_table(diff, md)
317-
md.new_line("<!-- end-socket-alerts-table -->")
318-
md.new_line()
319-
md = Messages.create_next_steps(md, next_steps)
320-
md = Messages.create_deeper_look(md)
321-
md = Messages.create_remove_package(md)
322-
md = Messages.create_acceptable_risk(md, ignore_commands)
323-
md.create_md_file()
324-
return md.file_data_text.lstrip()
311+
# Start of the comment
312+
comment = """<!-- socket-security-comment-actions -->
313+
314+
> **❗️ Caution**
315+
> **Review the following alerts detected in dependencies.**
316+
>
317+
> According to your organization’s Security Policy, you **must** resolve all **“Block”** alerts before proceeding. It’s recommended to resolve **“Warn”** alerts too.
318+
> Learn more about [Socket for GitHub](https://socket.dev?utm_medium=gh).
319+
320+
<!-- start-socket-updated-alerts-table -->
321+
<table>
322+
<thead>
323+
<tr>
324+
<th>Action</th>
325+
<th>Severity</th>
326+
<th align="left">Alert (click for details)</th>
327+
</tr>
328+
</thead>
329+
<tbody>
330+
"""
331+
332+
# Loop through alerts, dynamically generating rows
333+
for alert in diff.new_alerts:
334+
severity_icon = Messages.get_severity_icon(alert.severity)
335+
action = "Block" if alert.error else "Warn"
336+
details_open = ""
337+
# Generate a table row for each alert
338+
comment += f"""
339+
<!-- start-socket-alert-{alert.pkg_name}@{alert.pkg_version} -->
340+
<tr>
341+
<td><strong>{action}</strong></td>
342+
<td align="center">
343+
<img src="{severity_icon}" alt="{alert.severity}" width="20" height="20">
344+
</td>
345+
<td>
346+
<details {details_open}>
347+
<summary>{alert.pkg_name}@{alert.pkg_version} - {alert.title}</summary>
348+
<p><strong>Note:</strong> {alert.description}</p>
349+
<p><strong>Source:</strong> <a href="{alert.manifests}">Manifest File</a></p>
350+
<p>ℹ️ Read more on:
351+
<a href="{alert.purl}">This package</a> |
352+
<a href="{alert.url}">This alert</a> |
353+
<a href="https://socket.dev/alerts/malware">What is known malware?</a></p>
354+
<blockquote>
355+
<p><em>Suggestion:</em> {alert.suggestion}</p>
356+
<p><em>Mark as acceptable risk:</em> To ignore this alert only in this pull request, reply with:<br/>
357+
<code>@SocketSecurity ignore {alert.pkg_name}@{alert.pkg_version}</code><br/>
358+
Or ignore all future alerts with:<br/>
359+
<code>@SocketSecurity ignore-all</code></p>
360+
</blockquote>
361+
</details>
362+
</td>
363+
</tr>
364+
<!-- end-socket-alert-{alert.pkg_name}@{alert.pkg_version} -->
365+
"""
366+
367+
# Close table and comment
368+
comment += """
369+
</tbody>
370+
</table>
371+
<!-- end-socket-alerts-table -->
372+
373+
[View full report](https://socket.dev/...&action=error%2Cwarn)
374+
"""
375+
376+
return comment
377+
378+
@staticmethod
379+
def get_severity_icon(severity: str) -> str:
380+
"""
381+
Maps severity levels to their corresponding badge/icon URLs.
382+
383+
:param severity: str - Severity level (e.g., "Critical", "High").
384+
:return: str - Badge/icon URL.
385+
"""
386+
severity_map = {
387+
"critical": "https://github-app-statics.socket.dev/severity-3.svg",
388+
"high": "https://github-app-statics.socket.dev/severity-2.svg",
389+
"medium": "https://github-app-statics.socket.dev/severity-1.svg",
390+
"low": "https://github-app-statics.socket.dev/severity-0.svg",
391+
}
392+
return severity_map.get(severity.lower(), "https://github-app-statics.socket.dev/severity-0.svg")
393+
325394

326395
@staticmethod
327396
def create_next_steps(md: MdUtils, next_steps: dict):
@@ -456,11 +525,9 @@ def dependency_overview_template(diff: Diff) -> str:
456525
md = MdUtils(file_name="markdown_overview_temp.md")
457526
md.new_line("<!-- socket-overview-comment-actions -->")
458527
md.new_header(level=1, title="Socket Security: Dependency Overview")
459-
md.new_line("New and removed dependencies detected. Learn more about [socket.dev](https://socket.dev)")
528+
md.new_line("Review the following changes in direct dependencies. Learn more about [socket.dev](https://socket.dev)")
460529
md.new_line()
461530
md = Messages.create_added_table(diff, md)
462-
if len(diff.removed_packages) > 0:
463-
md = Messages.create_remove_line(diff, md)
464531
md.create_md_file()
465532
if len(md.file_data_text.lstrip()) >= 65500:
466533
md = Messages.short_dependency_overview_comment(diff)
@@ -471,7 +538,7 @@ def short_dependency_overview_comment(diff: Diff) -> MdUtils:
471538
md = MdUtils(file_name="markdown_overview_temp.md")
472539
md.new_line("<!-- socket-overview-comment-actions -->")
473540
md.new_header(level=1, title="Socket Security: Dependency Overview")
474-
md.new_line("New and removed dependencies detected. Learn more about [socket.dev](https://socket.dev)")
541+
md.new_line("Review the following changes in direct dependencies. Learn more about [socket.dev](https://socket.dev)")
475542
md.new_line()
476543
md.new_line("The amount of dependency changes were to long for this comment. Please check out the full report")
477544
md.new_line(f"To view more information about this report checkout the [Full Report]({diff.diff_url})")
@@ -498,40 +565,63 @@ def create_remove_line(diff: Diff, md: MdUtils) -> MdUtils:
498565
def create_added_table(diff: Diff, md: MdUtils) -> MdUtils:
499566
"""
500567
Create the Added packages table for the Dependency Overview template
501-
:param diff: Diff - Diff report with the Added packages information
568+
:param diff: Diff - Diff report with the Added package information
502569
:param md: MdUtils - Main markdown variable
503570
:return:
504571
"""
572+
# Table column headers
505573
overview_table = [
574+
"Diff",
506575
"Package",
507-
"Direct",
508-
"Capabilities",
509-
"Transitives",
510-
"Size",
511-
"Author"
576+
"Supply Chain<br/>Security",
577+
"Vulnerability",
578+
"Quality",
579+
"Maintenance",
580+
"License"
512581
]
513582
num_of_overview_columns = len(overview_table)
583+
514584
count = 0
515585
for added in diff.new_packages:
516-
added: Purl
517-
package_url = Messages.create_purl_link(added)
518-
capabilities = ", ".join(added.capabilities)
586+
added: Purl # Ensure `added` has scores and relevant attributes.
587+
588+
package_url = f"[{added.purl}]({added.url})"
589+
diff_badge = f"[![+](https://github-app-statics.socket.dev/diff-added.svg)]({added.url})"
590+
591+
# Scores dynamically converted to badge URLs and linked
592+
def score_to_badge(score):
593+
score_percent = int(score * 100) # Convert to integer percentage
594+
return f"[![{score_percent}](https://github-app-statics.socket.dev/score-{score_percent}.svg)]({added.url})"
595+
596+
# Generate badges for each score type
597+
supply_chain_risk_badge = score_to_badge(added.scores.get("supplyChain", 100))
598+
vulnerability_badge = score_to_badge(added.scores.get("vulnerability", 100))
599+
quality_badge = score_to_badge(added.scores.get("quality", 100))
600+
maintenance_badge = score_to_badge(added.scores.get("maintenance", 100))
601+
license_badge = score_to_badge(added.scores.get("license", 100))
602+
603+
# Add the row for this package
519604
row = [
605+
diff_badge,
520606
package_url,
521-
added.direct,
522-
capabilities,
523-
added.transitives,
524-
f"{added.size} KB",
525-
added.author_url
607+
supply_chain_risk_badge,
608+
vulnerability_badge,
609+
quality_badge,
610+
maintenance_badge,
611+
license_badge
526612
]
527613
overview_table.extend(row)
528-
count += 1
529-
num_of_overview_rows = count + 1
614+
count += 1 # Count total packages
615+
616+
# Calculate total rows for table
617+
num_of_overview_rows = count + 1 # Include header row
618+
619+
# Generate Markdown table
530620
md.new_table(
531621
columns=num_of_overview_columns,
532622
rows=num_of_overview_rows,
533623
text=overview_table,
534-
text_align="left"
624+
text_align="center"
535625
)
536626
return md
537627

0 commit comments

Comments
 (0)