Manage weekly report recipients centrally
Some checks failed
OfficeCom Sentinel Client / validate-client (push) Successful in 23s
OfficeCom Sentinel Client / build-client-windows (push) Failing after 19s

This commit is contained in:
OfficeCom Codex
2026-07-26 11:09:26 +02:00
parent 854c99e3b2
commit dfdae7a532
7 changed files with 156 additions and 9 deletions

View File

@@ -1,10 +1,11 @@
import hashlib
import hmac
import json
import os
from functools import wraps
import psycopg
from flask import Flask, Response, abort, render_template
from flask import Flask, Response, abort, redirect, render_template, request, url_for
app = Flask(__name__)
@@ -35,6 +36,17 @@ def requires_auth(view):
return wrapped
def csrf_token():
secret = os.environ["DASHBOARD_CSRF_SECRET"].encode("utf-8")
return hmac.new(secret, b"recipient-rules", hashlib.sha256).hexdigest()
def require_csrf():
supplied = request.form.get("csrf_token", "")
if not hmac.compare_digest(supplied, csrf_token()):
abort(400)
@app.get("/")
@requires_auth
def overview():
@@ -134,6 +146,80 @@ def weekly_report(report_id):
return render_template("weekly_report.html", report=report)
@app.get("/recipients")
@requires_auth
def recipients():
with db_connection() as connection, connection.cursor() as cursor:
cursor.execute(
"""
SELECT id, organization_id, organization_name, recipient_email, enabled
FROM ocsentinel.organization_report_recipient
ORDER BY organization_id = '*', organization_name, recipient_email
"""
)
rules = cursor.fetchall()
cursor.execute(
"""
SELECT DISTINCT payload #>> '{NinjaOne,OrganizationId}',
payload #>> '{NinjaOne,OrganizationName}'
FROM ocsentinel.current_device_status
WHERE coalesce(payload #>> '{NinjaOne,OrganizationId}', '') <> ''
ORDER BY 2
"""
)
organizations = cursor.fetchall()
return render_template("recipients.html", rules=rules, organizations=organizations, csrf_token=csrf_token())
@app.post("/recipients")
@requires_auth
def add_recipient():
require_csrf()
organization_id = request.form.get("organization_id", "").strip()
organization_name = request.form.get("organization_name", "").strip()
recipient_email = request.form.get("recipient_email", "").strip().lower()
if not organization_id or not organization_name or "@" not in recipient_email:
abort(400)
with db_connection() as connection, connection.cursor() as cursor:
cursor.execute(
"""
INSERT INTO ocsentinel.organization_report_recipient
(organization_id, organization_name, recipient_email)
VALUES (%s, %s, %s)
ON CONFLICT (organization_id, recipient_email) DO NOTHING
""",
(organization_id, organization_name, recipient_email),
)
connection.commit()
return redirect(url_for("recipients"))
@app.post("/recipients/<int:rule_id>/toggle")
@requires_auth
def toggle_recipient(rule_id):
require_csrf()
with db_connection() as connection, connection.cursor() as cursor:
cursor.execute(
"UPDATE ocsentinel.organization_report_recipient SET enabled = NOT enabled WHERE id = %s",
(rule_id,),
)
connection.commit()
return redirect(url_for("recipients"))
@app.post("/recipients/<int:rule_id>/delete")
@requires_auth
def delete_recipient(rule_id):
require_csrf()
with db_connection() as connection, connection.cursor() as cursor:
cursor.execute("DELETE FROM ocsentinel.organization_report_recipient WHERE id = %s", (rule_id,))
connection.commit()
return redirect(url_for("recipients"))
@app.get("/healthz")
def healthz():
try: