From 5ee0f71e625df91b4c74d1ad76a718468595fe74 Mon Sep 17 00:00:00 2001 From: Joseph Nuthalapati Date: Wed, 3 Oct 2018 15:36:02 -0700 Subject: [PATCH] shadowsocks: Enable backup/restore Reviewed-by: James Valleroy --- functional_tests/features/shadowsocks.feature | 9 ++++++ .../step_definitions/application.py | 20 ++++++++++++- functional_tests/support/application.py | 16 ++++++++--- plinth/modules/shadowsocks/__init__.py | 2 ++ plinth/modules/shadowsocks/manifest.py | 28 +++++++++++++++++++ 5 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 plinth/modules/shadowsocks/manifest.py diff --git a/functional_tests/features/shadowsocks.feature b/functional_tests/features/shadowsocks.feature index b2e8c040e..a3c7cb5d0 100644 --- a/functional_tests/features/shadowsocks.feature +++ b/functional_tests/features/shadowsocks.feature @@ -34,3 +34,12 @@ Scenario: Disable shadowsocks application When I disable the shadowsocks application Then the shadowsocks service should not be running +Scenario: Backup and restore shadowsocks + Given the shadowsocks application is enabled + When I configure shadowsocks with server beforebackup.example.com and password beforebackup123 + And I create a backup of the shadowsocks app data + And I configure shadowsocks with server afterbackup.example.com and password afterbackup123 + And I export the shadowsocks app data backup + And I restore the shadowsocks app data backup + Then the shadowsocks service should be running + And shadowsocks should be configured with server beforebackup.example.com and password beforebackup123 diff --git a/functional_tests/step_definitions/application.py b/functional_tests/step_definitions/application.py index 400059cd5..bcab8354c 100644 --- a/functional_tests/step_definitions/application.py +++ b/functional_tests/step_definitions/application.py @@ -96,7 +96,25 @@ def select_domain_name(browser, app_name, domain_name): @given('the shadowsocks application is configured') def configure_shadowsocks(browser): - application.configure_shadowsocks(browser) + application.configure_shadowsocks(browser, 'some.shadow.tunnel', + 'fakepassword') + + +@when( + parsers.parse( + 'I configure shadowsocks with server {server:S} and password {password:w}' + )) +def configure_shadowsocks_with_details(browser, server, password): + application.configure_shadowsocks(browser, server, password) + + +@then( + parsers.parse( + 'shadowsocks should be configured with server {server:S} and password {password:w}' + )) +def assert_shadowsocks_configuration(browser, server, password): + assert (server, + password) == application.shadowsocks_get_configuration(browser) @when( diff --git a/functional_tests/support/application.py b/functional_tests/support/application.py index ab52c0e78..4d5e6b6d0 100644 --- a/functional_tests/support/application.py +++ b/functional_tests/support/application.py @@ -116,14 +116,22 @@ def select_domain_name(browser, app_name, domain_name): interface.submit(browser, form_class='form-configuration') -def configure_shadowsocks(browser): - """Configure shadowsocks client with some fake server details""" +def configure_shadowsocks(browser, server, password): + """Configure shadowsocks client with given server details.""" browser.visit('{}/plinth/apps/shadowsocks/'.format(default_url)) - browser.find_by_id('id_server').fill('some.shadow.tunnel') - browser.find_by_id('id_password').fill('fakepassword') + browser.find_by_id('id_server').fill(server) + browser.find_by_id('id_password').fill(password) interface.submit(browser, form_class='form-configuration') +def shadowsocks_get_configuration(browser): + """Return the server and password currently configured in shadowsocks.""" + browser.visit('{}/plinth/apps/shadowsocks/'.format(default_url)) + server = browser.find_by_id('id_server').value + password = browser.find_by_id('id_password').value + return server, password + + def modify_max_file_size(browser, size): """Change the maximum file size of coquelicot to the given value""" browser.visit('{}/plinth/apps/coquelicot/'.format(default_url)) diff --git a/plinth/modules/shadowsocks/__init__.py b/plinth/modules/shadowsocks/__init__.py index ad6ccd4a4..50ea3254e 100644 --- a/plinth/modules/shadowsocks/__init__.py +++ b/plinth/modules/shadowsocks/__init__.py @@ -26,6 +26,8 @@ from plinth import action_utils, actions, cfg, frontpage from plinth.menu import main_menu from plinth.utils import format_lazy +from .manifest import backup + version = 1 name = _('Shadowsocks') diff --git a/plinth/modules/shadowsocks/manifest.py b/plinth/modules/shadowsocks/manifest.py new file mode 100644 index 000000000..c985e3c8d --- /dev/null +++ b/plinth/modules/shadowsocks/manifest.py @@ -0,0 +1,28 @@ +# +# 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 . +# +""" +Application manifest for shadowsocks. +""" + +from plinth.modules.backups.api import validate as validate_backup + +backup = validate_backup({ + 'secrets': { + 'files': ['/etc/shadowsocks-libev/freedombox.json'] + }, + 'services': ['shadowsocks-libev-local@freedombox'] +})