openvpn: Add backup/restore support

- Add functional tests

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2019-01-18 14:21:47 -08:00 committed by James Valleroy
parent 1d42081c62
commit c35cecb34a
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
6 changed files with 141 additions and 7 deletions

View File

@ -0,0 +1,46 @@
#
# 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 <http://www.gnu.org/licenses/>.
#
@apps @openvpn @backups
Feature: OpenVPN - Virtual Private Network
Setup and configure OpenVPN
Background:
Given I'm a logged in user
Given the openvpn application is installed
Given the openvpn application is setup
Scenario: Enable openvpn application
Given the openvpn application is disabled
When I enable the openvpn application
Then the openvpn service should be running
Scenario: Download openvpn profile
Given the openvpn application is enabled
Then the openvpn profile should be downloadable
Scenario: Backup and restore openvpn
Given the openvpn application is enabled
And I download openvpn profile
When I create a backup of the openvpn app data
And I restore the openvpn app data backup
Then the openvpn profile downloaded should be same as before
Scenario: Disable openvpn application
Given the openvpn application is enabled
When I disable the openvpn application
Then the openvpn service should not be running

View File

@ -25,7 +25,7 @@ from support import application
@given(parsers.parse('the {app_name:w} application is installed'))
def application_is_installed(browser, app_name):
application.install(browser, app_name)
assert(application.is_installed(browser, app_name))
assert (application.is_installed(browser, app_name))
@given(parsers.parse('the {app_name:w} application is enabled'))
@ -331,14 +331,19 @@ def tor_assert_download_software_over_tor(browser, enabled):
application.tor_assert_feature_enabled(browser, 'software', enabled)
@then(parsers.parse('{domain:S} should be a tahoe {introducer_type:w} introducer'))
@then(
parsers.parse(
'{domain:S} should be a tahoe {introducer_type:w} introducer'))
def tahoe_assert_introducer(browser, domain, introducer_type):
assert application.tahoe_get_introducer(browser, domain, introducer_type)
@then(parsers.parse('{domain:S} should not be a tahoe {introducer_type:w} introducer'))
@then(
parsers.parse(
'{domain:S} should not be a tahoe {introducer_type:w} introducer'))
def tahoe_assert_not_introducer(browser, domain, introducer_type):
assert not application.tahoe_get_introducer(browser, domain, introducer_type)
assert not application.tahoe_get_introducer(browser, domain,
introducer_type)
@given(parsers.parse('{domain:S} is not a tahoe introducer'))
@ -397,3 +402,24 @@ def radicale_check_owner_write(browser):
@then('the access rights should be "any user can view or make changes"')
def radicale_check_authenticated(browser):
assert application.radicale_get_access_rights(browser) == 'authenticated'
@given(parsers.parse('the openvpn application is setup'))
def openvpn_setup(browser):
application.openvpn_setup(browser)
@given('I download openvpn profile')
def openvpn_download_profile(browser):
return application.openvpn_download_profile(browser)
@then('the openvpn profile should be downloadable')
def openvpn_profile_downloadable(browser):
application.openvpn_download_profile(browser)
@then('the openvpn profile downloaded should be same as before')
def openvpn_profile_download_compare(browser, openvpn_download_profile):
new_profile = application.openvpn_download_profile(browser)
assert openvpn_download_profile == new_profile

View File

@ -17,6 +17,7 @@
from time import sleep
import requests
import splinter
from support import config, interface, site
@ -32,6 +33,7 @@ app_module = {
app_checkbox_id = {
'tor': 'id_tor-enabled',
'openvpn': 'id_openvpn-enabled',
}
default_url = config['DEFAULT']['url']
@ -115,6 +117,16 @@ def wait_for_config_update(browser, app_name):
sleep(0.1)
def _download_file(browser, url):
"""Return file contents after downloading a URL."""
cookies = browser.cookies.all()
response = requests.get(url, cookies=cookies, verify=False)
if response.status_code != 200:
raise Exception('URL download failed')
return response.content
def select_domain_name(browser, app_name, domain_name):
browser.visit('{}/plinth/apps/{}/setup/'.format(default_url, app_name))
drop_down = browser.find_by_id('id_domain_name')
@ -439,3 +451,21 @@ def radicale_set_access_rights(browser, access_rights_type):
interface.nav_to_module(browser, 'radicale')
browser.choose('access_rights', access_rights_type)
interface.submit(browser, form_class='form-configuration')
def openvpn_setup(browser):
"""Setup the OpenVPN application after installation."""
interface.nav_to_module(browser, 'openvpn')
setup_form = browser.find_by_css('.form-setup')
if not setup_form:
return
submit(browser, form_class='form-setup')
wait_for_config_update(browser, 'openvpn')
def openvpn_download_profile(browser):
"""Download the current user's profile into a file and return path."""
interface.nav_to_module(browser, 'openvpn')
url = browser.find_by_css('.form-profile')['action']
return _download_file(browser, url)

View File

@ -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 = 2
service = None

View File

@ -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 <http://www.gnu.org/licenses/>.
#
"""
Application manifest for OpenVPN.
"""
from plinth.modules.backups.api import validate as validate_backup
backup = validate_backup({
'secrets': {
'directories': ['/etc/openvpn/']
}
})

View File

@ -58,7 +58,8 @@
{% endblocktrans %}
</p>
<form class="form" method="post" action="{% url 'openvpn:profile' %}">
<form class="form form-profile" method="post"
action="{% url 'openvpn:profile' %}">
{% csrf_token %}
<input type="submit" class="btn btn-primary"
@ -79,7 +80,8 @@
{% endblocktrans %}
</p>
<form class="form" method="post" action="{% url 'openvpn:setup' %}">
<form class="form form-setup" method="post"
action="{% url 'openvpn:setup' %}">
{% csrf_token %}
<input type="submit" class="btn btn-primary"
@ -118,7 +120,7 @@
<h3>{% trans "Configuration" %}</h3>
<form class="form" method="post">
<form class="form form-configuration" method="post">
{% csrf_token %}
{{ form|bootstrap }}