From 623dbb4cbf2624efaf328eefdc4f440b5c2eae79 Mon Sep 17 00:00:00 2001 From: James Valleroy Date: Mon, 13 Aug 2018 20:56:15 -0400 Subject: [PATCH] backups: Validate backup manifests Signed-off-by: James Valleroy Reviewed-by: Joseph Nuthalapati --- plinth/backup.py | 49 ++++++++++++++++++++++++ plinth/modules/dynamicdns/manifest.py | 6 ++- plinth/modules/ejabberd/manifest.py | 5 ++- plinth/modules/ikiwiki/manifest.py | 5 ++- plinth/modules/infinoted/manifest.py | 5 ++- plinth/modules/matrixsynapse/manifest.py | 5 ++- plinth/modules/mediawiki/manifest.py | 5 ++- plinth/modules/minetest/manifest.py | 5 ++- plinth/modules/radicale/manifest.py | 5 ++- plinth/modules/repro/manifest.py | 5 ++- 10 files changed, 77 insertions(+), 18 deletions(-) create mode 100644 plinth/backup.py diff --git a/plinth/backup.py b/plinth/backup.py new file mode 100644 index 000000000..7930062e4 --- /dev/null +++ b/plinth/backup.py @@ -0,0 +1,49 @@ +# +# This file is part of FreedomBox. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +""" +Utility methods for providing backup information. +""" + + +def validate(backup): + """Validate the backup' information schema.""" + assert isinstance(backup, dict) + + assert 'config' in backup + assert isinstance(backup['config'], dict) + _validate_directories_and_files(backup['config']) + + assert 'data' in backup + assert isinstance(backup['data'], dict) + _validate_directories_and_files(backup['data']) + + assert 'secrets' in backup + assert isinstance(backup['secrets'], dict) + _validate_directories_and_files(backup['secrets']) + + assert 'services' in backup + assert isinstance(backup['services'], list) + + return backup + + +def _validate_directories_and_files(df): + """Validate directories and files structure.""" + assert 'directories' in df + assert isinstance(df['directories'], list) + assert 'files' in df + assert isinstance(df['files'], list) diff --git a/plinth/modules/dynamicdns/manifest.py b/plinth/modules/dynamicdns/manifest.py index a3c6e7078..c09a9e684 100644 --- a/plinth/modules/dynamicdns/manifest.py +++ b/plinth/modules/dynamicdns/manifest.py @@ -15,7 +15,9 @@ # along with this program. If not, see . # -backup = { +from plinth.backup import validate as validate_backup + +backup = validate_backup({ 'config': { 'directories': ['/etc/ez-ipupdate/'], 'files': [], @@ -29,4 +31,4 @@ backup = { 'files': [], }, 'services': [] -} +}) diff --git a/plinth/modules/ejabberd/manifest.py b/plinth/modules/ejabberd/manifest.py index b36b19991..d460ffb0d 100644 --- a/plinth/modules/ejabberd/manifest.py +++ b/plinth/modules/ejabberd/manifest.py @@ -17,6 +17,7 @@ from django.utils.translation import ugettext_lazy as _ +from plinth.backup import validate as validate_backup from plinth.clients import store_url, validate from plinth.modules.jsxc import manifest as jsxc_manifest @@ -121,7 +122,7 @@ _clients.extend(jsxc_manifest.clients) clients = _clients -backup = { +backup = validate_backup({ 'config': { 'directories': [], 'files': ['/etc/ejabberd/ejabberd.yml'], @@ -135,4 +136,4 @@ backup = { 'files': ['/etc/ejabberd/ejabberd.pem'], }, 'services': ['ejabberd'] -} +}) diff --git a/plinth/modules/ikiwiki/manifest.py b/plinth/modules/ikiwiki/manifest.py index 553f87314..2a95b712d 100644 --- a/plinth/modules/ikiwiki/manifest.py +++ b/plinth/modules/ikiwiki/manifest.py @@ -17,6 +17,7 @@ from django.utils.translation import ugettext_lazy as _ +from plinth.backup import validate as validate_backup from plinth.clients import validate clients = validate([{ @@ -27,7 +28,7 @@ clients = validate([{ }] }]) -backup = { +backup = validate_backup({ 'config': { 'directories': [], 'files': [], @@ -41,4 +42,4 @@ backup = { 'files': [], }, 'services': [] -} +}) diff --git a/plinth/modules/infinoted/manifest.py b/plinth/modules/infinoted/manifest.py index 085307c64..74b73807d 100644 --- a/plinth/modules/infinoted/manifest.py +++ b/plinth/modules/infinoted/manifest.py @@ -18,6 +18,7 @@ from django.utils.translation import ugettext_lazy as _ from plinth import cfg +from plinth.backup import validate as validate_backup from plinth.clients import validate from plinth.utils import format_lazy @@ -46,7 +47,7 @@ clients = validate([{ }] }]) -backup = { +backup = validate_backup({ 'config': { 'directories': [], 'files': [], @@ -63,4 +64,4 @@ backup = { ], }, 'services': ['infinoted'] -} +}) diff --git a/plinth/modules/matrixsynapse/manifest.py b/plinth/modules/matrixsynapse/manifest.py index f6cd58e65..f29ae4713 100644 --- a/plinth/modules/matrixsynapse/manifest.py +++ b/plinth/modules/matrixsynapse/manifest.py @@ -17,6 +17,7 @@ from django.utils.translation import ugettext_lazy as _ +from plinth.backup import validate as validate_backup from plinth.clients import store_url, validate _android_package_id = 'im.vector.alpha' @@ -53,7 +54,7 @@ clients = validate([{ }] }]) -backup = { +backup = validate_backup({ 'config': { 'directories': ['/etc/matrix-synapse/conf.d/'], 'files': [ @@ -78,4 +79,4 @@ backup = { ], }, 'services': ['matrix-synapse'] -} +}) diff --git a/plinth/modules/mediawiki/manifest.py b/plinth/modules/mediawiki/manifest.py index 0f17408d1..cd0d27008 100644 --- a/plinth/modules/mediawiki/manifest.py +++ b/plinth/modules/mediawiki/manifest.py @@ -17,6 +17,7 @@ from django.utils.translation import ugettext_lazy as _ +from plinth.backup import validate as validate_backup from plinth.clients import validate clients = validate([{ @@ -27,7 +28,7 @@ clients = validate([{ }] }]) -backup = { +backup = validate_backup({ 'config': { 'directories': [], 'files': [], @@ -41,4 +42,4 @@ backup = { 'files': [], }, 'services': [] -} +}) diff --git a/plinth/modules/minetest/manifest.py b/plinth/modules/minetest/manifest.py index 9591028de..0f44d528d 100644 --- a/plinth/modules/minetest/manifest.py +++ b/plinth/modules/minetest/manifest.py @@ -17,6 +17,7 @@ from django.utils.translation import ugettext_lazy as _ +from plinth.backup import validate as validate_backup from plinth.clients import store_url, validate clients = validate([{ @@ -51,7 +52,7 @@ clients = validate([{ }] }]) -backup = { +backup = validate_backup({ 'config': { 'directories': [], 'files': ['/etc/minetest/minetest.conf'], @@ -65,4 +66,4 @@ backup = { 'files': [], }, 'services': ['minetest-server'] -} +}) diff --git a/plinth/modules/radicale/manifest.py b/plinth/modules/radicale/manifest.py index afffcabc6..a4ca0a5c6 100644 --- a/plinth/modules/radicale/manifest.py +++ b/plinth/modules/radicale/manifest.py @@ -17,6 +17,7 @@ from django.utils.translation import ugettext_lazy as _ +from plinth.backup import validate as validate_backup from plinth.clients import store_url, validate clients = validate([{ @@ -86,7 +87,7 @@ clients = validate([{ }] }]) -backup = { +backup = validate_backup({ 'config': { 'directories': [], 'files': [], @@ -100,4 +101,4 @@ backup = { 'files': [], }, 'services': ['radicale'] -} +}) diff --git a/plinth/modules/repro/manifest.py b/plinth/modules/repro/manifest.py index 4410390a2..9171fd376 100644 --- a/plinth/modules/repro/manifest.py +++ b/plinth/modules/repro/manifest.py @@ -17,6 +17,7 @@ from django.utils.translation import ugettext_lazy as _ +from plinth.backup import validate as validate_backup from plinth.clients import store_url, validate _jitsi_package_id = 'org.jitsi.meet' @@ -74,7 +75,7 @@ clients = validate([{ }] }]) -backup = { +backup = validate_backup({ 'config': { 'directories': [], 'files': ['/etc/repro/repro.config', '/etc/repro/users.txt'], @@ -88,4 +89,4 @@ backup = { 'files': ['/etc/repro/dh2048.pem'], }, 'services': ['repro'] -} +})