Skip to content

Commit

Permalink
new: [webservice] Added possibility to execute background maintenance…
Browse files Browse the repository at this point in the history
… tasks via the admin panel (backup database and update MISP warning lists).
  • Loading branch information
cedricbonhomme committed Sep 18, 2024
1 parent 7e433b8 commit f36053b
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 3 deletions.
24 changes: 24 additions & 0 deletions website/lib/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import json
import re
import requests
import shlex
import subprocess

from sqlalchemy import func, desc

Expand All @@ -14,6 +16,28 @@
from website.web.bootstrap import db



def exec_cmd(command: str) -> str:
"""Execute a command in a sub process and wait for the result."""
homedir = get_homedir()
bash_string = r"""#!/bin/bash
set -e
{}
""".format(
command
)
result = subprocess.check_output(
bash_string, shell=True, executable="/bin/bash", text=True, cwd=get_homedir()
)
return result.strip()


def exec_cmd_no_wait(command: str) -> None:
"""Execute a command in a sub process."""
args = shlex.split(command)
subprocess.Popen(args, stdout=subprocess.PIPE, cwd=get_homedir())


def find_cve_ids(text: str) -> List[str]:
"""Find CVE IDs in a text. Returns a list of string."""
# Regex pattern to match CVE IDs (e.g., CVE-2021-34527 or cve-2021-34527)
Expand Down
41 changes: 39 additions & 2 deletions website/web/templates/admin/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ <h2 id="instance-status">Instance status</h2>
</div>
</div>
<br />
<div class="row">
<div class="col">
<h2 id="instance-status">Maintenance</h2>
<button id="maintenance-warning-lists" class="btn btn-primary" type="button" title="Update the MISP Warning lists in background.">Update MISP Warning lists</button>
<button id="maintenance-backup-database" class="btn btn-primary" type="button" title="Backup the database in background.">Backup database</button>
</div>
</div>
<br />
<div class="row">
<div class="col">
<h2 id="storage">Storage</h2>
Expand All @@ -50,13 +58,42 @@ <h2 id="storage">Storage</h2>
<div class="col">
<h2 id="active-users">Active users</h2>
{{ users_templates.table_users(users=users) }}
<p><a href="{{ url_for('admin_bp.list_users') }}">All users</a>.</p>
</div>
</div>
<br />
<script>
document.addEventListener("DOMContentLoaded", function() {
var jsonContainer = document.getElementById("json-container");
jsonContainer.innerHTML = prettyPrintJson.toHtml(JSON.parse(jsonContainer.innerText));
var jsonContainer = document.getElementById("json-container");
jsonContainer.innerHTML = prettyPrintJson.toHtml(JSON.parse(jsonContainer.innerText));

document.getElementById("maintenance-warning-lists").addEventListener('click',function (event)
{
rpc_maintainance("/admin/command/update_warninglists");
})

document.getElementById("maintenance-backup-database").addEventListener('click',function (event)
{
rpc_maintainance("/admin/command/backup_database");
})
});

function rpc_maintainance(url) {
fetch(url)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json(); // or response.text() for plain text
})
.then(data => {
// console.log(data);
alert(data["message"]);
})
.catch(error => {
// console.error('There has been a problem during the operation:', error);
alert('There has been a problem during the operation:', error);
});
}
</script>
{% endblock %}
2 changes: 1 addition & 1 deletion website/web/templates/admin/users.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
{% block content %}
<h2>Status</h2>
<ul class="list-group">
<li class="list-group-item">Two-Factor Authentication: {% if config["ENFORCE_2FA"] %}Enforced{% else %}Not enforced{% endif %}</li>
<li class="list-group-item">Number of users: {{ total_nb_users }}</li>
<li class="list-group-item">Two-Factor Authentication: {% if config["ENFORCE_2FA"] %}Enforced{% else %}Not enforced{% endif %}</li>
<li class="list-group-item">Not using Two-Factor Authentication: {{ nb_users_without_2fa }}</li>
</ul>
<br />
Expand Down
18 changes: 18 additions & 0 deletions website/web/views/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from flask import abort
from flask import Blueprint
from flask import flash
from flask import jsonify
from flask import redirect
from flask import render_template
from flask import url_for
Expand All @@ -20,6 +21,7 @@

from vulnerabilitylookup.default import get_config
from website.models import User, Comment, Bundle
from website.lib.utils import exec_cmd_no_wait
from website.web.bootstrap import db
from website.web.bootstrap import vulnerabilitylookup
from website.web.forms import UserForm
Expand Down Expand Up @@ -53,6 +55,22 @@ def dashboard() -> str:
)


@admin_bp.route("/command/backup_database", methods=["GET"])
@login_required # type: ignore[misc]
@admin_permission.require(http_exception=403) # type: ignore[misc]
def backup_database() -> WerkzeugResponse:
exec_cmd_no_wait('poetry run flask --app website.app db_backup')
return jsonify({"message": "Command executed."})


@admin_bp.route("/command/update_warninglists", methods=["GET"])
@login_required # type: ignore[misc]
@admin_permission.require(http_exception=403) # type: ignore[misc]
def update_warninglists() -> WerkzeugResponse:
exec_cmd_no_wait('poetry run flask --app website.app update_warninglists')
return jsonify({"message": "Command executed."})


#
# Users
#
Expand Down

0 comments on commit f36053b

Please sign in to comment.