Skip to content

Commit

Permalink
feat: auto create GitHub issues for new vulnerabilities
Browse files Browse the repository at this point in the history
  • Loading branch information
dervoeti committed Nov 25, 2024
1 parent 94c89d8 commit 4406daf
Showing 1 changed file with 51 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import json
import os
from dataclasses import dataclass
from typing import Optional, Tuple
from typing import Any, Optional, Tuple

import requests
from django.core.files.base import File
from django.utils import timezone
from rest_framework.exceptions import ValidationError
Expand Down Expand Up @@ -517,6 +519,11 @@ def _process_new_observation(imported_observation: Observation) -> None:
else None
)

issue_id = _get_github_issue_id(
imported_observation
)
if issue_id:
imported_observation.issue_tracker_issue_id = issue_id
# Observation has not been imported before, so it is a new one
epss_apply_observation(imported_observation)
imported_observation.save()
Expand Down Expand Up @@ -593,6 +600,49 @@ def _get_initial_status(product: Product) -> str:
return Status.STATUS_OPEN


def _get_github_issue_id(observation: Observation) -> Optional[str]:
github_pat = os.getenv("GITHUB_ISSUES_PAT")
if not github_pat:
return None

# Find observation with the same title and "issue_tracker_issue_id" set
issue_number = (
Observation.objects.filter(
title=observation.title, issue_tracker_issue_id__isnull=False
)
.values_list("issue_tracker_issue_id", flat=True)
.first()
)

if not issue_number:
print(f"Creating new issue for vulnerability_id: {observation.title}")
data: dict[str, Any] = {
"title": observation.title,
"body": f"""[Show observations in SecObserve](https://secobserve.stackable.tech/#/observations?displayedFilters=%7B%7D&filter=%7B%22current_status%22%3A%22Open%22%2C%22title%22%3A%22{observation.title}%22%7D&order=DESC&page=1&perPage=500&sort=branch_name)
[Review assessments in SecObserve](https://secobserve.stackable.tech/#/observation_logs/needs_approval?displayedFilters=%7B%7D&filter=%7B%22observation_title%22%3A%22{observation.title}%22%7D&order=ASC&page=1&perPage=25&sort=created)
[Show completed assessments in SecObserve](https://secobserve.stackable.tech/#/observations?displayedFilters=%7B%7D&filter=%7B%22has_completed_assessment%22%3Atrue%2C%22title%22%3A%22{observation.title}%22%7D&order=DESC&page=1&perPage=500&sort=branch_name)
---
### {observation.title}
{observation.description}""",
}
response = requests.post(
url="https://api.github.com/repos/stackabletech/vulnerabilities/issues",
headers={
"Accept": "application/vnd.github+json",
"Authorization": f"Bearer {github_pat}",
},
data=json.dumps(data),
timeout=60,
)
response.raise_for_status()
issue_number = response.json().get("number")
return issue_number


class ParserError(Exception):
def __init__(self, message):
self.message = message

0 comments on commit 4406daf

Please sign in to comment.