Use API for config.json

This commit is contained in:
amcmanu3 2023-08-15 16:09:06 -04:00
parent 4e0743bc1f
commit 93428b2e05
4 changed files with 182 additions and 27 deletions

View File

@ -5,6 +5,7 @@ from datetime import datetime
import platform
import shutil
import time
import json
import logging
import threading
from peewee import DoesNotExist
@ -84,6 +85,13 @@ class Controller:
def set_project_root(self, root_dir):
self.project_root = root_dir
def set_config_json(self, data):
keys = list(data.keys())
keys.sort()
sorted_data = {i: data[i] for i in keys}
with open(self.helper.settings_file, "w", encoding="utf-8") as f:
json.dump(sorted_data, f, indent=4)
def package_support_logs(self, exec_user):
if exec_user["preparing"]:
return

View File

@ -49,6 +49,7 @@ from app.classes.web.routes.api.users.user.permissions import (
)
from app.classes.web.routes.api.users.user.pfp import ApiUsersUserPfpHandler
from app.classes.web.routes.api.users.user.public import ApiUsersUserPublicHandler
from app.classes.web.routes.api.crafty.config.index import ApiCraftyConfigIndexHandler
def api_handlers(handler_args):
@ -64,6 +65,11 @@ def api_handlers(handler_args):
ApiAuthInvalidateTokensHandler,
handler_args,
),
(
r"/api/v2/crafty/config/?",
ApiCraftyConfigIndexHandler,
handler_args,
),
# User routes
(
r"/api/v2/users/?",

View File

@ -0,0 +1,113 @@
from jsonschema import ValidationError, validate
import orjson
from playhouse.shortcuts import model_to_dict
from app.classes.web.base_api_handler import BaseApiHandler
config_json_schema = {
"type": "object",
"properties": {
"http_port": {"type": "integer"},
"https_port": {"type": "integer"},
"language": {
"type": "string",
},
"cookie_expire": {"type": "integer"},
"show_errors": {"type": "boolean"},
"history_max_age": {"type": "integer"},
"stats_update_frequency_seconds": {"type": "integer"},
"delete_default_json": {"type": "boolean"},
"show_contribute_link": {"type": "boolean"},
"virtual_terminal_lines": {"type": "integer"},
"max_log_lines": {"type": "integer"},
"max_audit_entries": {"type": "integer"},
"disabled_language_files": {"type": "array"},
"stream_size_GB": {"type": "integer"},
"keywords": {"type": "string"},
"allow_nsfw_profile_pictures": {"type": "boolean"},
"enable_user_self_delete": {"type": "boolean"},
"reset_secrets_on_next_boot": {"type": "boolean"},
"monitored_mounts": {"type": "array"},
"dir_size_poll_freq_minutes": {"type": "integer"},
"crafty_logs_delete_after_days": {"type": "integer"},
},
"additionalProperties": False,
"minProperties": 1,
}
class ApiCraftyConfigIndexHandler(BaseApiHandler):
def get(self):
auth_data = self.authenticate_user()
if not auth_data:
return
(
_,
_,
_,
superuser,
_,
) = auth_data
# GET /api/v2/roles?ids=true
get_only_ids = self.get_query_argument("ids", None) == "true"
if not superuser:
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
self.finish_json(
200,
{
"status": "ok",
"data": self.controller.roles.get_all_role_ids()
if get_only_ids
else [model_to_dict(r) for r in self.controller.roles.get_all_roles()],
},
)
def patch(self):
auth_data = self.authenticate_user()
if not auth_data:
return
(
_,
_,
_,
superuser,
user,
) = auth_data
if not superuser:
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
try:
data = orjson.loads(self.request.body)
except orjson.decoder.JSONDecodeError as e:
return self.finish_json(
400, {"status": "error", "error": "INVALID_JSON", "error_data": str(e)}
)
try:
validate(data, config_json_schema)
except ValidationError as e:
return self.finish_json(
400,
{
"status": "error",
"error": "INVALID_JSON_SCHEMA",
"error_data": str(e),
},
)
self.controller.set_config_json(data)
self.controller.management.add_to_audit_log(
user["user_id"],
"edited config.json",
server_id=0,
source_ip=self.get_remote_ip(),
)
self.finish_json(
200,
{"status": "ok"},
)

View File

@ -50,7 +50,6 @@
<!-- Page Title Header Ends-->
<form id="config-form" class="forms-sample" method="post" action="/panel/config_json">
{% raw xsrf_form_html() %}
{% for item in data['config-json'].items() %}
{% if item[0] == "reset_secrets_on_next_boot" %}
@ -156,37 +155,66 @@
{% block js %}
<script>
$("#config-form").submit(function (e) {
let uuid = uuidv4();
var token = getCookie("_xsrf")
function replacer(key, value) {
if (key == "disabled_language_files") {
if (value == 0){
return []
} else {
return value
}
}
if (typeof value == "boolean") {
return value
} else {
return (isNaN(value) ? value : +value);
}
}
$("#config-form").on("submit", async function (e) {
e.preventDefault();
$("#submit-status").html('<i class="fa fa-spinner fa-spin"></i>');
/* Convert multiple select to text list */
let selected_Lang = $('#lang_select').val();
$('#disabled_lang').val(selected_Lang);
var token = getCookie("_xsrf")
let configForm = document.getElementById("config-form");
let mounts = $('#mount_select').val();
$('#monitored_mounts').val(mounts);
let formData = new FormData(configForm);
formData.delete("disabled_lang");
formData.delete("lang_select");
let class_list = document.getElementsByClassName("list");
let form_json = convertFormToJSON($("#config-form"));
for (let i = 0; i < class_list.length; i++) {
let str = String($(class_list.item(i)).val())
form_json[$(class_list.item(i)).attr("name")] = uuid + "," + str.replace(/\s/g, '');
};
form_json['uuid'] = uuid;
$.ajax({
type: "POST",
headers: { 'X-XSRFToken': token },
dataType: "text",
url: '/panel/config_json',
data: form_json,
success: function (data) {
$("#submit-status").html('<i class="fa fa-check"></i>');
},
//Create an object from the form data entries
let formDataObject = Object.fromEntries(formData.entries());
//We need to make sure these are sent regardless of whether or not they're checked
formDataObject.disabled_language_files = $('#lang_select').val();
formDataObject.monitored_mounts = $('#mount_select').val();
$('#config-form input[type="radio"]:checked').each(function() {
if ($(this).val() == 'True'){
formDataObject[this.name] = true;
}else{
formDataObject[this.name] = false;
}
});
});
console.log(formDataObject);
// Format the plain form data as JSON
let formDataJsonString = JSON.stringify(formDataObject, replacer);
console.log(formDataJsonString);
let res = await fetch(`/api/v2/crafty/config/`, {
method: 'PATCH',
headers: {
'X-XSRFToken': token
},
body: formDataJsonString,
});
let responseData = await res.json();
if (responseData.status === "ok") {
$("#submit-status").html('<i class="fa fa-check"></i>');
} else {
bootbox.alert({
title: responseData.error,
message: responseData.error_data
});
}
});
function uuidv4() {
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>