From b201cd6ca22a5c5b38b7dd7198aa0c989368b263 Mon Sep 17 00:00:00 2001 From: Illia Chub Date: Wed, 24 Nov 2021 07:59:55 +0200 Subject: [PATCH 1/5] Changed backup protocol to rclone --- selfprivacy_api/resources/services/restic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/selfprivacy_api/resources/services/restic.py b/selfprivacy_api/resources/services/restic.py index be911ca..4d75145 100644 --- a/selfprivacy_api/resources/services/restic.py +++ b/selfprivacy_api/resources/services/restic.py @@ -32,7 +32,7 @@ class ListAllBackups(Resource): backup_listing_command = [ "restic", "-r", - f"b2:{repository_name}:/sfbackup", + f"rclone:backblaze:{repository_name}:/sfbackup", "snapshots", "--json", ] @@ -72,7 +72,7 @@ class AsyncCreateBackup(Resource): backup_command = [ "restic", "-r", - f"b2:{repository_name}:/sfbackup", + f"rclone:backblaze:{repository_name}:/sfbackup", "--verbose", "--json", "backup", From 9a87fa43eb347c058134cc11b10bbc66a98018a1 Mon Sep 17 00:00:00 2001 From: Illia Chub Date: Thu, 25 Nov 2021 12:31:18 +0200 Subject: [PATCH 2/5] Added backup restoration endpoint --- selfprivacy_api/resources/services/restic.py | 39 ++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/selfprivacy_api/resources/services/restic.py b/selfprivacy_api/resources/services/restic.py index 4d75145..863d090 100644 --- a/selfprivacy_api/resources/services/restic.py +++ b/selfprivacy_api/resources/services/restic.py @@ -128,6 +128,45 @@ class CheckBackupStatus(Resource): return backup_process_status +class AsyncRestoreBackup(Resource): + """Trigger backup restoration process""" + + def put(self): + """ + Start backup restoration + --- + tags: + - Backups + security: + - bearerAuth: [] + responses: + 200: + description: Backup restoration process started + 400: + description: Bad request + 401: + description: Unauthorized + """ + backup_restoration_command = ["restic", "-r", "rclone:backblaze:sfbackup", "var", "--json"] + + with open("/tmp/backup.log", "w", encoding="utf-8") as backup_log_file_descriptor: + with subprocess.Popen( + backup_restoration_command, + shell=False, + stdout=subprocess.PIPE, + stderr=backup_log_file_descriptor, + ) as backup_restoration_process_descriptor: + backup_restoration_status = ( + "Backup restoration procedure started" + ) + + return { + "status": 0, + "message": backup_restoration_status + } + + api.add_resource(ListAllBackups, "/restic/backup/list") api.add_resource(AsyncCreateBackup, "/restic/backup/create") api.add_resource(CheckBackupStatus, "/restic/backup/status") +api.add_resource(AsyncRestoreBackup, "/restic/backup/restore") From fb98fd1e606c3a458a4d33c639839dff1d4bbd23 Mon Sep 17 00:00:00 2001 From: Illia Chub Date: Tue, 30 Nov 2021 07:04:06 +0200 Subject: [PATCH 3/5] Implemented update check endpoint --- selfprivacy_api/resources/services/update.py | 57 ++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 selfprivacy_api/resources/services/update.py diff --git a/selfprivacy_api/resources/services/update.py b/selfprivacy_api/resources/services/update.py new file mode 100644 index 0000000..4ef4a4b --- /dev/null +++ b/selfprivacy_api/resources/services/update.py @@ -0,0 +1,57 @@ +#!/usr/bin/env/python3 +"""Update dispatch module""" +import json +import os +import portalocker +import subprocess +from flask_restful import Resource, reqparse + +from selfprivacy_api.resources.services import api + + +class PullRepositoryChanges(Resource): + def get(self): + """ + Pull Repository Changes + --- + tags: + - Update + security: + - bearerAuth: [] + responses: + 200: + description: Got update + 201: + description: Nothing to update + 401: + description: Unauthorized + 500: + description: Something went wrong + """ + + git_pull_command = ["git", "pull"] + + + os.chdir("/etc/nixos") + git_pull_process_descriptor = subprocess.Popen( + git_pull_command, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + shell=False + ) + + + git_pull_process_descriptor.communicate()[0] + + if git_pull_process_descriptor.returncode == 0: + return { + "status": 0, + "message": "Update completed successfully" + } + elif git_pull_process_descriptor.returncode > 0: + return { + "status": git_pull_process_descriptor.returncode, + "message": "Something went wrong" + }, 500 + +api.add_resource(PullRepositoryChanges, "/update") From d1fdaf186d4ed28db9dbc6205200329f9ace77a2 Mon Sep 17 00:00:00 2001 From: Illia Chub Date: Tue, 30 Nov 2021 07:10:00 +0200 Subject: [PATCH 4/5] Mitigated possible directory escape scenario --- selfprivacy_api/resources/services/update.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/selfprivacy_api/resources/services/update.py b/selfprivacy_api/resources/services/update.py index 4ef4a4b..ff812b4 100644 --- a/selfprivacy_api/resources/services/update.py +++ b/selfprivacy_api/resources/services/update.py @@ -31,8 +31,10 @@ class PullRepositoryChanges(Resource): git_pull_command = ["git", "pull"] - + current_working_directory = os.getcwd() os.chdir("/etc/nixos") + + git_pull_process_descriptor = subprocess.Popen( git_pull_command, stdout=subprocess.PIPE, @@ -43,6 +45,8 @@ class PullRepositoryChanges(Resource): git_pull_process_descriptor.communicate()[0] + os.chdir(current_working_directory) + if git_pull_process_descriptor.returncode == 0: return { "status": 0, From 1385835a7fd9a49ef84043915a684e5c9de5c8f8 Mon Sep 17 00:00:00 2001 From: Illia Chub Date: Tue, 30 Nov 2021 07:12:04 +0200 Subject: [PATCH 5/5] Removed useless imports from update module --- selfprivacy_api/resources/services/update.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/selfprivacy_api/resources/services/update.py b/selfprivacy_api/resources/services/update.py index ff812b4..1d15fbe 100644 --- a/selfprivacy_api/resources/services/update.py +++ b/selfprivacy_api/resources/services/update.py @@ -1,8 +1,6 @@ #!/usr/bin/env/python3 """Update dispatch module""" -import json import os -import portalocker import subprocess from flask_restful import Resource, reqparse