diff --git a/actions/tor b/actions/tor index cb234a8bd..9f2da6c00 100755 --- a/actions/tor +++ b/actions/tor @@ -94,16 +94,16 @@ def subcommand_enable_hs(_): if get_hidden_service() != "": return - with open(TOR_CONFIG, 'r') as file: - lines = file.readlines() + with open(TOR_CONFIG, 'r') as conffile: + lines = conffile.readlines() lines.append("# Hidden Service configured by Plinth\n") lines.append("HiddenServiceDir /var/lib/tor/hidden_service/\n") lines.append("HiddenServicePort 80 127.0.0.1:80\n") lines.append("HiddenServicePort 443 127.0.0.1:443\n") - with open(TOR_CONFIG, 'w') as file: - file.writelines(lines) + with open(TOR_CONFIG, 'w') as conffile: + conffile.writelines(lines) subprocess.call(['service', 'tor', 'restart']) @@ -114,26 +114,28 @@ def subcommand_disable_hs(_): if not get_hidden_service(): return - with open(TOR_CONFIG, 'r') as file: - lines = file.readlines() + with open(TOR_CONFIG, 'r') as conffile: + lines = conffile.readlines() filtered_lines = [] removing = False for line in lines: if removing: if not line.startswith("HiddenService"): - # end of Plinth hidden service block -- stop removing lines + # end of Plinth hidden service block + # stop removing lines removing = False filtered_lines.append(line) else: if line.startswith("# Hidden Service configured by Plinth"): - # start of Plinth hidden service block -- remove following HiddenService lines + # start of Plinth hidden service block + # remove following HiddenService lines removing = True else: filtered_lines.append(line) - with open(TOR_CONFIG, 'w') as file: - file.writelines(filtered_lines) + with open(TOR_CONFIG, 'w') as conffile: + conffile.writelines(filtered_lines) subprocess.call(['service', 'tor', 'restart']) @@ -157,8 +159,8 @@ def get_hidden_service(): hs_dir = "" hs_ports = [] - with open(TOR_CONFIG, 'r') as file: - lines = file.readlines() + with open(TOR_CONFIG, 'r') as conffile: + lines = conffile.readlines() for line in lines: if line.startswith('HiddenServiceDir'): hs_dir = line.split()[1] @@ -168,8 +170,8 @@ def get_hidden_service(): if hs_dir == "": return "" - with open(hs_dir + 'hostname', 'r') as file: - hs_hostname = file.read().strip() + with open(hs_dir + 'hostname', 'r') as conffile: + hs_hostname = conffile.read().strip() return hs_hostname + ' ' + ','.join(hs_ports) diff --git a/plinth/modules/tor/templates/tor.html b/plinth/modules/tor/templates/tor.html index 7f24155c1..93e68c5fe 100644 --- a/plinth/modules/tor/templates/tor.html +++ b/plinth/modules/tor/templates/tor.html @@ -18,6 +18,8 @@ # {% endcomment %} +{% load bootstrap %} + {% block main_block %}

Status

@@ -38,6 +40,15 @@ Here is the current configuration:
  • Hostname: {{ tor_hs_hostname }}
  • Ports: {{ tor_hs_ports }}
  • + +
    + {% csrf_token %} + + {{ form|bootstrap }} + + +
    +

    Bridge

    diff --git a/plinth/modules/tor/tor.py b/plinth/modules/tor/tor.py index a3825d715..b1b1ff384 100644 --- a/plinth/modules/tor/tor.py +++ b/plinth/modules/tor/tor.py @@ -19,6 +19,8 @@ Plinth module for configuring Tor """ +from django import forms +from django.contrib import messages from django.contrib.auth.decorators import login_required from django.template.response import TemplateResponse from gettext import gettext as _ @@ -27,6 +29,13 @@ from plinth import actions from plinth import cfg +class TorForm(forms.Form): # pylint: disable=W0232 + """Tor configuration form""" + hs_enabled = forms.BooleanField( + label=_('Enable Hidden Service'), + required=False) + + def init(): """Initialize the Tor module""" menu = cfg.main_menu.get('apps:index') @@ -36,30 +45,74 @@ def init(): @login_required def index(request): """Service the index page""" - output = actions.superuser_run("tor-get-ports") + status = get_status() + form = None + + if request.method == 'POST': + form = TorForm(request.POST, prefix='tor') + # pylint: disable=E1101 + if form.is_valid(): + _apply_changes(request, status, form.cleaned_data) + status = get_status() + form = TorForm(initial=status, prefix='tor') + else: + form = TorForm(initial=status, prefix='tor') + + return TemplateResponse(request, 'tor.html', + {'title': _('Tor Control Panel'), + 'is_running': status['is_running'], + 'tor_ports': status['ports'], + 'tor_hs_enabled': status['hs_enabled'], + 'tor_hs_hostname': status['hs_hostname'], + 'tor_hs_ports': status['hs_ports'], + 'form': form}) + + +def get_status(): + """Return the current status""" + is_running = actions.superuser_run("tor", ["is-running"]).strip() == "yes" + + output = actions.superuser_run("tor-get-ports") port_info = output.split("\n") - tor_ports = {} + ports = {} for line in port_info: try: (key, val) = line.split() - tor_ports[key] = val + ports[key] = val except ValueError: continue output = actions.superuser_run("tor", ["get-hs"]) + output = output.strip() if output == "": - tor_hs_hostname = "Not Configured" - tor_hs_ports = "" + hs_enabled = False + hs_hostname = "Not Configured" + hs_ports = "" else: + hs_enabled = True hs_info = output.split() - tor_hs_hostname = hs_info[0] - tor_hs_ports = hs_info[1] + hs_hostname = hs_info[0] + hs_ports = hs_info[1] - is_running = actions.superuser_run("tor", ["is-running"]).strip() == "yes" - return TemplateResponse(request, 'tor.html', - {'title': _('Tor Control Panel'), - 'tor_hs_hostname': tor_hs_hostname, - 'tor_hs_ports': tor_hs_ports, - 'tor_ports': tor_ports, - 'is_running': is_running}) + return {'is_running': is_running, + 'ports': ports, + 'hs_enabled': hs_enabled, + 'hs_hostname': hs_hostname, + 'hs_ports': hs_ports} + + +def _apply_changes(request, old_status, new_status): + """Apply the changes""" + if old_status['hs_enabled'] == new_status['hs_enabled']: + messages.info(request, _('Setting unchanged')) + return + + if new_status['hs_enabled']: + messages.success(request, _('Tor hidden service enabled')) + command = 'enable-hs' + else: + messages.success(request, _('Tor hidden service disabled')) + command = 'disable-hs' + + actions.superuser_run('tor', [command])