File: views.py

package info (click to toggle)
freedombox 26.2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 82,976 kB
  • sloc: python: 48,504; javascript: 1,736; xml: 481; makefile: 290; sh: 167; php: 32
file content (104 lines) | stat: -rw-r--r-- 3,388 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# SPDX-License-Identifier: AGPL-3.0-or-later
"""FreedomBox app for configuring Tor Proxy."""

import logging

from django.utils.translation import gettext_noop
from django.views.generic.edit import FormView

from plinth import app as app_module
from plinth import operation as operation_module
from plinth.views import AppView

from . import privileged
from . import utils as tor_utils
from .forms import TorProxyForm

logger = logging.getLogger(__name__)


class TorProxyAppView(AppView):
    """Show Tor Proxy app main page."""

    app_id = 'torproxy'
    template_name = 'torproxy.html'
    form_class = TorProxyForm
    prefix = 'torproxy'

    status = None

    def get_initial(self):
        """Return the values to fill in the form."""
        if not self.status:
            self.status = tor_utils.get_status()

        initial = super().get_initial()
        initial.update(self.status)
        return initial

    def get_context_data(self, *args, **kwargs):
        """Add additional context data for template."""
        if not self.status:
            self.status = tor_utils.get_status()

        context = super().get_context_data(*args, **kwargs)
        context['status'] = self.status
        return context

    def form_valid(self, form):
        """Configure tor app on successful form submission."""
        operation_module.manager.new('torproxy-configuration', self.app_id,
                                     gettext_noop('Updating configuration'),
                                     _apply_changes,
                                     [form.initial, form.cleaned_data],
                                     show_notification=False)
        # Skip check for 'Settings unchanged' message by calling grandparent
        return super(FormView, self).form_valid(form)


def _apply_changes(old_status, new_status):
    """Try to apply changes and handle errors."""
    logger.info('torproxy: applying configuration changes')
    exception_to_update = None
    message = None
    try:
        __apply_changes(old_status, new_status)
    except Exception as exception:
        exception_to_update = exception
        message = gettext_noop('Error configuring app: {error}').format(
            error=exception)
    else:
        message = gettext_noop('Configuration updated.')

    logger.info('torproxy: configuration changes completed')
    operation = operation_module.Operation.get_operation()
    operation.on_update(message, exception_to_update)


def __apply_changes(old_status, new_status):
    """Apply the changes."""
    needs_restart = False
    arguments = {}

    app = app_module.App.get('torproxy')
    is_enabled = app.is_enabled()

    if old_status['apt_transport_tor_enabled'] != \
       new_status['apt_transport_tor_enabled']:
        arguments['apt_transport_tor'] = (
            is_enabled and new_status['apt_transport_tor_enabled'])

    if old_status['use_upstream_bridges'] != \
       new_status['use_upstream_bridges']:
        arguments['use_upstream_bridges'] = new_status['use_upstream_bridges']
        needs_restart = True

    if old_status['upstream_bridges'] != new_status['upstream_bridges']:
        arguments['upstream_bridges'] = new_status['upstream_bridges']
        needs_restart = True

    if arguments:
        privileged.configure(**arguments)

    if needs_restart and is_enabled:
        privileged.restart()