From f7decf4b4eed03dcfeda729c5a1ab221519ef2d4 Mon Sep 17 00:00:00 2001 From: CasVT Date: Sun, 3 Mar 2024 13:06:49 +0100 Subject: [PATCH] Added 'keep hosting settings' option for db import --- backend/db.py | 35 ++++++++++++++++++++++++++++++----- frontend/api.py | 6 +++--- frontend/input_validation.py | 13 +++++++++++++ frontend/static/css/admin.css | 9 ++++++++- frontend/static/js/admin.js | 4 +++- frontend/templates/admin.html | 26 +++++++++++++++++++------- 6 files changed, 76 insertions(+), 17 deletions(-) diff --git a/backend/db.py b/backend/db.py index 520c598..8214e93 100644 --- a/backend/db.py +++ b/backend/db.py @@ -425,16 +425,21 @@ def revert_db_import( return -def import_db(new_db_file: str) -> None: +def import_db( + new_db_file: str, + copy_hosting_settings: bool +) -> None: """Replace the current database with a new one. Args: new_db_file (str): The path to the new database file. + copy_hosting_settings (bool): Keep the hosting settings from the current + database. Raises: InvalidDatabaseFile: The new database file is invalid or unsupported. """ - logging.info(f'Importing new database') + logging.info(f'Importing new database; {copy_hosting_settings=}') try: cursor = Connection(new_db_file, timeout=20.0).cursor() @@ -446,15 +451,13 @@ def import_db(new_db_file: str) -> None: except (OperationalError, InvalidDatabaseFile): logging.error('Uploaded database is not a MIND database file') + cursor.connection.close() revert_db_import( swap=False, imported_db_file=new_db_file ) raise InvalidDatabaseFile - finally: - cursor.connection.close() - if database_version > __DATABASE_VERSION__: logging.error('Uploaded database is higher version than this MIND installation can support') revert_db_import( @@ -463,6 +466,28 @@ def import_db(new_db_file: str) -> None: ) raise InvalidDatabaseFile + if copy_hosting_settings: + hosting_settings = get_db().execute(""" + SELECT key, value, value + FROM config + WHERE key = 'host' + OR key = 'port' + OR key = 'url_prefix' + LIMIT 3; + """ + ) + cursor.executemany(""" + INSERT INTO config(key, value) + VALUES (?, ?) + ON CONFLICT(key) DO + UPDATE + SET value = ?; + """, + hosting_settings + ) + cursor.connection.commit() + cursor.connection.close() + move( DBConnection.file, join(dirname(DBConnection.file), __DATEBASE_NAME_ORIGINAL__) diff --git a/frontend/api.py b/frontend/api.py index ca5965d..ea055d3 100644 --- a/frontend/api.py +++ b/frontend/api.py @@ -29,7 +29,7 @@ from backend.server import SERVER from backend.settings import (backup_hosting_settings, get_admin_settings, get_setting, set_setting) from backend.users import Users -from frontend.input_validation import (AllowNewAccountsVariable, ColorVariable, +from frontend.input_validation import (AllowNewAccountsVariable, ColorVariable, CopyHostingSettingsVariable, DatabaseFileVariable, EditNotificationServicesVariable, EditTimeVariable, EditTitleVariable, @@ -792,7 +792,7 @@ def api_admin_user(inputs: Dict[str, Any], u_id: int): description="Download the database file" ), post=Method( - vars=[DatabaseFileVariable], + vars=[DatabaseFileVariable, CopyHostingSettingsVariable], description="Upload and apply a database file" ) ), @@ -822,5 +822,5 @@ def api_admin_database(inputs: Dict[str, Any]): ), 200 elif request.method == "POST": - import_db(inputs['file']) + import_db(inputs['file'], inputs['copy_hosting_settings']) return return_api({}) diff --git a/frontend/input_validation.py b/frontend/input_validation.py index 2bca0c5..18ace02 100644 --- a/frontend/input_validation.py +++ b/frontend/input_validation.py @@ -426,6 +426,19 @@ class DatabaseFileVariable(BaseInputVariable): return False +class CopyHostingSettingsVariable(BaseInputVariable): + name = 'copy_hosting_settings' + description = 'Copy the hosting settings from the current database' + source = DataSource.VALUES + + def validate(self) -> bool: + if not self.value in ('true', 'false'): + return False + + self.value = self.value == 'true' + return True + + def input_validation() -> Union[None, Dict[str, Any]]: """Checks, extracts and transforms inputs diff --git a/frontend/static/css/admin.css b/frontend/static/css/admin.css index d3ad90c..544fc2f 100644 --- a/frontend/static/css/admin.css +++ b/frontend/static/css/admin.css @@ -234,8 +234,15 @@ h2 { padding: .25rem; } +#upload-database-form { + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; +} + #hosting-form > p, -#upload-database-form p { +#upload-database-form > p { max-width: 50rem; margin-inline: auto; text-align: center; diff --git a/frontend/static/js/admin.js b/frontend/static/js/admin.js index 442281a..3965861 100644 --- a/frontend/static/js/admin.js +++ b/frontend/static/js/admin.js @@ -19,6 +19,7 @@ const user_inputs = { const import_inputs = { file: document.querySelector('#database-file-input'), + copy_hosting: document.querySelector('#copy-hosting-input'), button: document.querySelector('#upload-db-button') }; @@ -226,9 +227,10 @@ function loadUsers() { function upload_database() { import_inputs.button.innerText = 'Importing'; + const copy_hosting = import_inputs.copy_hosting.checked ? 'true' : 'false'; const formData = new FormData(); formData.append('file', import_inputs.file.files[0]); - fetch(`${url_prefix}/api/admin/database?api_key=${api_key}`, { + fetch(`${url_prefix}/api/admin/database?api_key=${api_key}©_hosting_settings=${copy_hosting}`, { method: 'POST', body: formData }) diff --git a/frontend/templates/admin.html b/frontend/templates/admin.html index c84e95b..243c695 100644 --- a/frontend/templates/admin.html +++ b/frontend/templates/admin.html @@ -83,14 +83,14 @@ -

Valid IPv4 address (default is '0.0.0.0' for all available interfaces)

+

Valid IPv4 address (default is '0.0.0.0' for all available interfaces).

-

The port used to access the web UI (default is '8080')

+

The port used to access the web UI (default is '8080').

@@ -156,14 +156,26 @@
-
- - +
+ + + + + + + + + + + +
+ +

Keep the current hosting settings instead of using the settings in the uploaded database.

+
+

Restore a backup.

-

Note: The uploaded file can be denied if it is not a valid database file, is too old or is for a newer version than this MIND instance.

-

IMPORTANT: After uploading the backup, it is required to log into the admin panel within 1 minute (60 seconds) in order to keep the new database file. Otherwise, MIND will revert the upload and go back to the old database.

Power