mkdocs for influxdb and smtp (#28)
* mkdocs for influxdb and smtp * precommit
taylor_socfortress committed
Jul 14, 2023 at 15:22 UTC
083a07f5044fdc5fff358c2d876dcda58c72773f
8 files changed
+148
-2
backend/app/routes/smtp.py
+6
-2
@@ -15,7 +15,9 @@ def put_credentials() -> jsonify:
15
Endpoint to store credentials into `smtp_credentials` table.
16
17
Returns:
18
- jsonify: A JSON response containing if the credentials were stored successfully.
18
+ Tuple[jsonify, int]: A Tuple where the first element is a JSON response
19
+ indicating if the credentials were stored successfully and the second element
20
+ is the HTTP status code.
21
"""
22
if not request.is_json:
23
return jsonify({"message": "Missing JSON in request", "success": False}), 400
@@ -52,7 +54,9 @@ def send_report() -> jsonify:
54
Endpoint to send a report via email.
55
56
Returns:
55
- jsonify: A JSON response containing if the report was sent successfully.
57
+ Tuple[jsonify, int]: A Tuple where the first element is a JSON response
58
+ indicating if the report was sent successfully and the second element
59
+ is the HTTP status code.
60
"""
61
logger.info("Received request to send a report via email")
62
if not request.is_json:
backend/app/services/InfluxDB/__init__.py
backend/app/services/smtp/__init__.py
backend/app/services/smtp/create_report.py
+49
@@ -16,12 +16,33 @@ from app.services.WazuhIndexer.alerts import AlertsService
16
17
18
def fetch_alert_data(service, fetch_func):
19
+ """
20
+ Fetches alert data using the provided function.
21
+
22
+ Args:
23
+ service: An instance of the service to use for fetching data.
24
+ fetch_func (function): The function to use to fetch the data.
25
+
26
+ Returns:
27
+ Returns the result of the fetch function.
28
+ """
29
alerts = fetch_func()
30
logger.info(alerts)
31
return alerts
32
33
34
def create_bar_chart(alerts: dict, title: str, output_filename: str) -> None:
35
+ """
36
+ Creates a horizontal bar chart of alerts and saves it to a file.
37
+
38
+ Args:
39
+ alerts (dict): A dictionary containing alert data.
40
+ title (str): The title for the chart.
41
+ output_filename (str): The filename to save the chart to.
42
+
43
+ Returns:
44
+ None
45
+ """
46
entities = [alert["hostname"] for alert in alerts["alerts_by_host"]]
47
num_alerts = [alert["number_of_alerts"] for alert in alerts["alerts_by_host"]]
48
@@ -35,6 +56,17 @@ def create_bar_chart(alerts: dict, title: str, output_filename: str) -> None:
56
57
58
def create_pie_chart(alerts: dict, title: str, output_filename: str) -> None:
59
+ """
60
+ Creates a pie chart of alerts and saves it to a file.
61
+
62
+ Args:
63
+ alerts (dict): A dictionary containing alert data.
64
+ title (str): The title for the chart.
65
+ output_filename (str): The filename to save the chart to.
66
+
67
+ Returns:
68
+ None
69
+ """
70
entities = [alert["rule"] for alert in alerts["alerts_by_rule"]]
71
num_alerts = [alert["number_of_alerts"] for alert in alerts["alerts_by_rule"]]
72
@@ -46,6 +78,17 @@ def create_pie_chart(alerts: dict, title: str, output_filename: str) -> None:
78
79
80
def create_pdf(title: str, image_filenames: List[str], pdf_filename: str) -> None:
81
+ """
82
+ Creates a PDF containing images.
83
+
84
+ Args:
85
+ title (str): The title for the PDF.
86
+ image_filenames (List[str]): A list of image filenames to include in the PDF.
87
+ pdf_filename (str): The filename to save the PDF to.
88
+
89
+ Returns:
90
+ None
91
+ """
92
c = canvas.Canvas(pdf_filename, pagesize=letter)
93
width, height = letter
94
c.setFont("Helvetica", 24)
@@ -58,6 +101,12 @@ def create_pdf(title: str, image_filenames: List[str], pdf_filename: str) -> Non
101
102
103
def create_alerts_report_pdf() -> None:
104
+ """
105
+ Creates a PDF report of alerts including a bar chart and a pie chart.
106
+
107
+ Returns:
108
+ None
109
+ """
110
service = AlertsService()
111
112
alerts_by_host = fetch_alert_data(service, service.collect_alerts_by_host)
backend/app/services/smtp/send_report.py
+45
@@ -11,16 +11,44 @@ from app.services.smtp.universal import UniversalEmailCredentials
11
12
13
class EmailReportSender:
14
+ """
15
+ Class for sending an email report with PDF attachments.
16
+ """
17
+
18
def __init__(self, to_email: str):
19
+ """
20
+ Constructor for the EmailReportSender class.
21
+
22
+ Args:
23
+ to_email (str): The email address to send the report to.
24
+ """
25
self.to_email = to_email
26
27
def _get_credentials(self) -> dict:
28
+ """
29
+ Fetches the email credentials.
30
+
31
+ Returns:
32
+ dict: A dictionary containing the email credentials. If no credentials are found,
33
+ the dictionary contains an "error" key.
34
+ """
35
try:
36
return UniversalEmailCredentials.read_all()["emails_configured"][0]
37
except IndexError:
38
return {"error": "No email credentials found"}
39
40
def create_email_message(self, subject: str, body: str) -> MIMEMultipart:
41
+ """
42
+ Creates an email message with the provided subject and body.
43
+
44
+ Args:
45
+ subject (str): The subject of the email.
46
+ body (str): The body of the email.
47
+
48
+ Returns:
49
+ MIMEMultipart: An email message object. If an error occurs while fetching credentials,
50
+ the return value is a dictionary containing an "error" key.
51
+ """
52
msg = MIMEMultipart()
53
credentials = self._get_credentials()
54
if "error" in credentials:
@@ -32,6 +60,16 @@ class EmailReportSender:
60
return msg
61
62
def attach_pdfs(self, msg: MIMEMultipart, filenames: List[str]) -> MIMEMultipart:
63
+ """
64
+ Attaches PDF files to an email message.
65
+
66
+ Args:
67
+ msg (MIMEMultipart): The email message to attach the PDFs to.
68
+ filenames (List[str]): A list of filenames of the PDFs to attach.
69
+
70
+ Returns:
71
+ MIMEMultipart: The email message with the attached PDFs.
72
+ """
73
for filename in filenames:
74
with open(filename, "rb") as attachment_file:
75
part = MIMEBase("application", "octet-stream")
@@ -42,6 +80,13 @@ class EmailReportSender:
80
return msg
81
82
def send_email_with_pdf(self):
83
+ """
84
+ Sends an email with a PDF report.
85
+
86
+ Returns:
87
+ dict: A dictionary containing a "message" key describing the result of the operation
88
+ and a "success" key indicating whether the operation was successful.
89
+ """
90
# Generate the PDF report
91
create_alerts_report_pdf()
92
backend/docs/influxdb.md
new
+21
@@ -0,0 +1,21 @@
1
+## InfluxDB Overview
2
+
3
+### <span style="color:blue">Alerts Model</span>
4
+
5
+::: app.models.influxdb_alerts
6
+<br>
7
+
8
+### <span style="color:green">Checks Routes</span>
9
+
10
+### <span style="color:green">Alerts Routes</span>
11
+
12
+::: app.routes.influxdb
13
+<br>
14
+
15
+### <span style="color:red">Checks Services</span>
16
+
17
+::: app.services.InfluxDB.checks
18
+
19
+### <span style="color:red">Alerts Services</span>
20
+
21
+::: app.services.InfluxDB.alerts
backend/docs/smtp.md
new
+25
@@ -0,0 +1,25 @@
1
+## SMTP Overview
2
+
3
+### <span style="color:blue">EmailCredentials Model</span>
4
+
5
+::: app.models.smtp
6
+<br>
7
+
8
+### <span style="color:green">Checks Routes</span>
9
+
10
+### <span style="color:green">Alerts Routes</span>
11
+
12
+::: app.routes.smtp
13
+<br>
14
+
15
+### <span style="color:red">Create Report Services</span>
16
+
17
+::: app.services.smtp.create_report
18
+
19
+### <span style="color:red">Send Report Services</span>
20
+
21
+::: app.services.smtp.send_report
22
+
23
+### <span style="color:red">Universal Services</span>
24
+
25
+::: app.services.smtp.universal
backend/mkdocs.yml
+2
@@ -42,6 +42,8 @@ nav:
42
- Velociraptor: velociraptor.md
43
- Shuffle: shuffle.md
44
- Sublime: sublime.md
45
+ - InfluxDB: influxdb.md
46
+ - SMTP: smtp.md
47
48
markdown_extensions:
49
- pymdownx.highlight: