# SPDX-License-Identifier: AGPL-3.0-or-later """ FreedomBox app for configuring OpenVPN server. """ import logging from django.contrib import messages from django.http import HttpResponse from django.shortcuts import redirect from django.template.response import TemplateResponse from django.utils.translation import ugettext as _ from django.views.decorators.http import require_POST from plinth import actions, daemon from plinth.modules import config, openvpn from .forms import OpenVpnForm logger = logging.getLogger(__name__) setup_process = None def index(request): """Serve configuration page.""" status = get_status() if status['setup_running']: _collect_setup_result(request) form = None if request.method == 'POST': form = OpenVpnForm(request.POST, prefix='openvpn') # pylint: disable=E1101 if form.is_valid(): _apply_changes(request, status, form.cleaned_data) status = get_status() form = OpenVpnForm(initial=status, prefix='openvpn') else: form = OpenVpnForm(initial=status, prefix='openvpn') return TemplateResponse( request, 'openvpn.html', { 'app_id': 'openvpn', 'app_info': openvpn.app.info, 'port_forwarding_info': openvpn.port_forwarding_info, 'status': status, 'form': form, 'show_status_block': True, 'is_running': status['is_running'], 'has_diagnostics': True, 'is_enabled': status['enabled'], }) @require_POST def setup(request): """Start the setup process.""" global setup_process if not openvpn.is_setup() and not setup_process: setup_process = actions.superuser_run('openvpn', ['setup'], run_in_background=True) openvpn.app.enable() return redirect('openvpn:index') def profile(request): """Provide the user's profile for download.""" username = request.user.username domainname = config.get_domainname() if not config.get_domainname(): domainname = config.get_hostname() profile_string = actions.superuser_run( 'openvpn', ['get-profile', username, domainname]) response = HttpResponse(profile_string, content_type='application/x-openvpn-profile') response['Content-Disposition'] = \ 'attachment; filename={username}.ovpn'.format(username=username) return response def get_status(): """Get the current settings from OpenVPN server.""" return { 'is_setup': openvpn.is_setup(), 'setup_running': bool(setup_process), 'enabled': openvpn.app.is_enabled(), 'is_running': daemon.app_is_running(openvpn.app) } def _collect_setup_result(request): """Handle setup process is completion.""" global setup_process if not setup_process: return return_code = setup_process.poll() # Setup process is not complete yet if return_code is None: return if not return_code: messages.success(request, _('Setup completed.')) else: messages.info(request, _('Setup failed.')) setup_process = None def _apply_changes(request, old_status, new_status): """Apply the changes.""" modified = False if old_status['enabled'] != new_status['enabled']: if new_status['enabled']: openvpn.app.enable() else: openvpn.app.disable() modified = True if modified: messages.success(request, _('Configuration updated')) else: messages.info(request, _('Setting unchanged'))