Introduce firewall component for opening/closing ports

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-05-21 09:08:35 -07:00 committed by James Valleroy
parent 4c4a59e5fe
commit ca2c7dbeb0
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
48 changed files with 647 additions and 401 deletions

View File

@ -147,8 +147,6 @@ def main():
log.init()
service.init()
web_framework.init()
logger.info('FreedomBox Service (Plinth) version - %s', __version__)

View File

@ -74,10 +74,7 @@ class App:
"""
for component in self.components.values():
if not component.is_leader:
if enabled:
component.enable()
else:
component.disable()
component.set_enabled(enabled)
class Component:
@ -93,10 +90,10 @@ class Component:
self.component_id = component_id
def enable(self):
"""Enable the component."""
"""Run operations to enable the component."""
def disable(self):
"""Disable the component."""
"""Run operations to disable the component."""
class FollowerComponent(Component):
@ -117,12 +114,16 @@ class FollowerComponent(Component):
"""Return whether the component is enabled."""
return self._is_enabled
def set_enabled(self, enabled):
"""Update the internal enabled state of the component."""
self._is_enabled = enabled
def enable(self):
"""Enable the component."""
"""Run operations to enable the component."""
self._is_enabled = True
def disable(self):
"""Disable the component."""
"""Run operations to disable the component."""
self._is_enabled = False

View File

@ -18,7 +18,13 @@
FreedomBox app for Apache server.
"""
from django.utils.translation import ugettext_lazy as _
from plinth import actions
from plinth import app as app_module
from plinth import cfg
from plinth.modules.firewall.components import Firewall
from plinth.utils import format_lazy
version = 7
@ -26,9 +32,38 @@ is_essential = True
managed_packages = ['apache2', 'php-fpm']
app = None
class ApacheApp(app_module.App):
"""FreedomBox app for Apache web server."""
def __init__(self):
"""Create components for the app."""
super().__init__()
web_server_ports = Firewall('firewall-web', _('Web Server'),
ports=['http', 'https'], is_external=True)
self.add(web_server_ports)
freedombox_ports = Firewall(
'firewall-plinth',
format_lazy(
_('{box_name} Web Interface (Plinth)'), box_name=_(
cfg.box_name)), ports=['http', 'https'], is_external=True)
self.add(freedombox_ports)
def init():
"""Initailze firewall module"""
global app
app = ApacheApp()
app.set_enabled(True)
def setup(helper, old_version=None):
"""Configure the module."""
helper.install(managed_packages)
actions.superuser_run('apache',
['setup', '--old-version', str(old_version)])
actions.superuser_run(
'apache',
['setup', '--old-version', str(old_version)])

View File

@ -24,6 +24,7 @@ from plinth import actions
from plinth import app as app_module
from plinth import cfg, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.utils import format_lazy
from plinth.views import ServiceView
@ -69,6 +70,10 @@ class AvahiApp(app_module.App):
'avahi:index', parent_url_name='system')
self.add(menu_item)
firewall = Firewall('firewall-avahi', name, ports=['mdns'],
is_external=False)
self.add(firewall)
def init():
"""Intialize the service discovery module."""
@ -77,8 +82,7 @@ def init():
app.set_enabled(True)
global service # pylint: disable=W0603
service = service_module.Service(managed_services[0], name, ports=['mdns'],
is_external=False)
service = service_module.Service(managed_services[0], name)
def setup(helper, old_version=None):

View File

@ -26,6 +26,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import cfg, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.utils import format_lazy
from .manifest import backup
@ -97,6 +98,10 @@ class BindApp(app_module.App):
parent_url_name='system')
self.add(menu_item)
firewall = Firewall('firewall-bind', name, ports=['dns'],
is_external=False)
self.add(firewall)
def init():
"""Intialize the BIND module."""
@ -106,8 +111,7 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name,
ports=['dns'], is_external=False)
service = service_module.Service(managed_services[0], name)
app.set_enabled(True) # XXX: Perform better check
@ -117,9 +121,7 @@ def setup(helper, old_version=None):
global service
if service is None:
service = service_module.Service(managed_services[0], name,
ports=['dns'], is_external=True,
enable=enable, disable=disable)
helper.call('post', service.notify_enabled, None, True)
helper.call('post', actions.superuser_run, 'bind', ['setup'])
helper.call('post', app.enable)

View File

@ -26,6 +26,7 @@ from plinth import app as app_module
from plinth import cfg, frontpage, menu
from plinth import service as service_module
from plinth.modules import names
from plinth.modules.firewall.components import Firewall
from plinth.signals import domain_added, domain_removed, domainname_change
from plinth.utils import format_lazy
@ -80,6 +81,10 @@ class CockpitApp(app_module.App):
clients=clients, login_required=True)
self.add(shortcut)
firewall = Firewall('firewall-cockpit', name, ports=['http', 'https'],
is_external=True)
self.add(firewall)
def init():
"""Intialize the module."""
@ -89,9 +94,8 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
service = service_module.Service(managed_services[0], name,
is_enabled=is_enabled, enable=enable,
disable=disable)
if is_enabled():
@ -112,11 +116,9 @@ def setup(helper, old_version=None):
helper.call('post', actions.superuser_run, 'cockpit', ['setup'] + domains)
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
service = service_module.Service(managed_services[0], name,
is_enabled=is_enabled, enable=enable,
disable=disable)
helper.call('post', service.notify_enabled, None, True)
helper.call('post', app.enable)

View File

@ -24,6 +24,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from .manifest import backup, clients
@ -73,6 +74,11 @@ class CoquelicotApp(app_module.App):
clients=clients, login_required=True)
self.add(shortcut)
firewall = Firewall('firewall-coquelicot', name,
ports=['http', 'https'], is_external=True)
self.add(firewall)
def init():
"""Intialize the module."""
@ -82,11 +88,9 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
disable=disable,
is_running=is_running)
service = service_module.Service(
managed_services[0], name, is_enabled=is_enabled, enable=enable,
disable=disable, is_running=is_running)
if is_enabled():
app.set_enabled(True)
@ -99,12 +103,9 @@ def setup(helper, old_version=None):
helper.call('post', actions.superuser_run, 'coquelicot', ['enable'])
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
disable=disable,
is_running=is_running)
helper.call('post', service.notify_enabled, None, True)
service = service_module.Service(
managed_services[0], name, is_enabled=is_enabled, enable=enable,
disable=disable, is_running=is_running)
helper.call('post', app.enable)

View File

@ -70,18 +70,15 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name,
is_external=True)
service = service_module.Service(managed_services[0], name)
def setup(helper, old_version=None):
"""Install and configure the module."""
global service
if service is None:
service = service_module.Service(managed_services[0], name,
is_external=True)
service = service_module.Service(managed_services[0], name)
service.enable()
helper.call('post', service.notify_enabled, None, True)
helper.call('post', app.enable)

View File

@ -24,6 +24,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.modules.users import register_group
from .manifest import backup, clients
@ -75,6 +76,10 @@ class DelugeApp(app_module.App):
allowed_groups=[group[0]])
self.add(shortcut)
firewall = Firewall('firewall-deluge', name, ports=['http', 'https'],
is_external=True)
self.add(firewall)
def init():
"""Initialize the Deluge module."""
@ -85,9 +90,8 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
service = service_module.Service(managed_services[0], name,
is_enabled=is_enabled, enable=enable,
disable=disable)
if is_enabled():
app.set_enabled(True)
@ -99,11 +103,9 @@ def setup(helper, old_version=None):
helper.call('post', actions.superuser_run, 'deluge', ['enable'])
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
service = service_module.Service(managed_services[0], name,
is_enabled=is_enabled, enable=enable,
disable=disable)
helper.call('post', service.notify_enabled, None, True)
helper.call('post', app.enable)

View File

@ -24,6 +24,7 @@ from plinth import app as app_module
from plinth import frontpage, menu
from plinth import service as service_module
from plinth.errors import DomainNotRegisteredError
from plinth.modules.firewall.components import Firewall
from plinth.utils import format_lazy
domain_name_file = "/etc/diaspora/domain_name"
@ -92,6 +93,10 @@ class DiasporaApp(app_module.App):
icon='diaspora', url=None, clients=clients, login_required=True)
self.add(shortcut)
firewall = Firewall('firewall-diaspora', name, ports=['http', 'https'],
is_external=True)
self.add(firewall)
class Shortcut(frontpage.Shortcut):
"""Frontpage shortcut to use configured domain name for URL."""
@ -110,9 +115,8 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
service = service_module.Service(managed_services[0], name,
is_enabled=is_enabled, enable=enable,
disable=disable)
if is_enabled():
@ -131,11 +135,9 @@ def setup_domain_name(domain_name):
actions.superuser_run('diaspora', ['setup', '--domain-name', domain_name])
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
service = service_module.Service(managed_services[0], name,
is_enabled=is_enabled, enable=enable,
disable=disable)
service.notify_enabled(None, True)
app.enable()

View File

@ -28,6 +28,7 @@ from plinth import app as app_module
from plinth import cfg, frontpage, menu
from plinth import service as service_module
from plinth.modules import config
from plinth.modules.firewall.components import Firewall
from plinth.signals import (domainname_change, post_hostname_change,
pre_hostname_change)
from plinth.utils import format_lazy
@ -94,6 +95,11 @@ class EjabberdApp(app_module.App):
login_required=True)
self.add(shortcut)
firewall = Firewall('firewall-ejabberd', name,
ports=['xmpp-client', 'xmpp-server',
'xmpp-bosh'], is_external=True)
self.add(firewall)
def init():
"""Initialize the ejabberd module"""
@ -103,11 +109,9 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(
'ejabberd', name,
ports=['xmpp-client', 'xmpp-server',
'xmpp-bosh'], is_external=True, is_enabled=is_enabled,
enable=enable, disable=disable)
service = service_module.Service('ejabberd', name,
is_enabled=is_enabled, enable=enable,
disable=disable)
if is_enabled():
app.set_enabled(True)
@ -127,12 +131,9 @@ def setup(helper, old_version=None):
helper.call('post', actions.superuser_run, 'ejabberd', ['setup'])
global service
if service is None:
service = service_module.Service(
'ejabberd', name,
ports=['xmpp-client', 'xmpp-server',
'xmpp-bosh'], is_external=True, is_enabled=is_enabled,
enable=enable, disable=disable)
helper.call('post', service.notify_enabled, None, True)
service = service_module.Service('ejabberd', name,
is_enabled=is_enabled, enable=enable,
disable=disable)
helper.call('post', app.enable)

View File

@ -18,15 +18,11 @@
FreedomBox app to configure a firewall.
"""
import logging
from django.utils.translation import ugettext_lazy as _
import plinth.service as service_module
from plinth import actions
from plinth import app as app_module
from plinth import cfg, menu
from plinth.signals import service_enabled
from plinth.utils import Version, format_lazy
from .manifest import backup
@ -49,8 +45,6 @@ description = [
manual_page = 'Firewall'
LOGGER = logging.getLogger(__name__)
_port_details = {}
app = None
@ -73,8 +67,6 @@ def init():
app = FirewallApp()
app.set_enabled(True)
service_enabled.connect(on_service_enabled)
def setup(helper, old_version=None):
"""Install and configure the module."""
@ -139,51 +131,6 @@ def remove_service(port, zone):
_run(['remove-service', port, '--zone', zone], superuser=True)
def on_service_enabled(sender, service_id, enabled, **kwargs):
"""
Enable/disable firewall ports when a service is
enabled/disabled.
"""
del sender # Unused
del kwargs # Unused
internal_enabled_services = get_enabled_services(zone='internal')
external_enabled_services = get_enabled_services(zone='external')
LOGGER.info('Service enabled - %s, %s', service_id, enabled)
service = service_module.services[service_id]
for port in service.ports:
if enabled:
if port not in internal_enabled_services:
add_service(port, zone='internal')
if (service.is_external and port not in external_enabled_services):
add_service(port, zone='external')
else:
# service already configured.
pass
else:
if port in internal_enabled_services:
enabled_services_on_port = [
service_.is_enabled()
for service_ in service_module.services.values()
if port in service_.ports
and service_id != service_.service_id
]
if not any(enabled_services_on_port):
remove_service(port, zone='internal')
if port in external_enabled_services:
enabled_services_on_port = [
service_.is_enabled()
for service_ in service_module.services.values()
if port in service_.ports and
service_id != service_.service_id and service_.is_external
]
if not any(enabled_services_on_port):
remove_service(port, zone='external')
def _run(arguments, superuser=False):
"""Run an given command and raise exception if there was an error"""
command = 'firewall'

View File

@ -0,0 +1,106 @@
#
# 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/>.
#
"""
App component for other apps to use firewall functionality.
"""
import logging
from plinth import app
from plinth.modules import firewall
logger = logging.getLogger(__name__)
class Firewall(app.FollowerComponent):
"""Component to open/close firewall ports for an app."""
_all_firewall_components = {}
def __init__(self, component_id, name=None, ports=None, is_external=False):
"""Initialize the firewall component."""
super().__init__(component_id)
if not ports:
ports = []
self.name = name
self.ports = ports
self.is_external = is_external
self._all_firewall_components[component_id] = self
@property
def ports_details(self):
"""Retrieve details of ports associated with this component.."""
ports_details = []
for port in self.ports:
ports_details.append({
'name': port,
'details': firewall.get_port_details(port),
})
return ports_details
@classmethod
def list(cls):
"""Return a list of all firewall ports."""
return cls._all_firewall_components.values()
def enable(self):
"""Open firewall ports when the component is enabled."""
super().enable()
internal_enabled_ports = firewall.get_enabled_services(zone='internal')
external_enabled_ports = firewall.get_enabled_services(zone='external')
logger.info('Firewall ports opened - %s, %s', self.name, self.ports)
for port in self.ports:
if port not in internal_enabled_ports:
firewall.add_service(port, zone='internal')
if (self.is_external and port not in external_enabled_ports):
firewall.add_service(port, zone='external')
def disable(self):
"""Close firewall ports when the component is disabled."""
super().disable()
internal_enabled_ports = firewall.get_enabled_services(zone='internal')
external_enabled_ports = firewall.get_enabled_services(zone='external')
logger.info('Firewall ports closed - %s, %s', self.name, self.ports)
for port in self.ports:
if port in internal_enabled_ports:
enabled_components_on_port = [
component.is_enabled()
for component in self._all_firewall_components.values()
if port in component.ports
and self.component_id != component.component_id
]
if not any(enabled_components_on_port):
firewall.remove_service(port, zone='internal')
if port in external_enabled_ports:
enabled_components_on_port = [
component.is_enabled()
for component in self._all_firewall_components.values()
if port in component.ports and self.component_id !=
component.component_id and component.is_external
]
if not any(enabled_components_on_port):
firewall.remove_service(port, zone='external')

View File

@ -46,19 +46,19 @@
</thead>
<tbody>
{% for service in services|dictsort:"name" %}
{% if service.ports %}
{% for component in components|dictsort:"name" %}
{% if component.ports %}
<tr>
<td>
<center>
<button data-toggle="collapse"
data-target=".{{service.service_id}}"
data-target=".{{component.component_id}}"
class="btn btn-info btn-xs">+</button>
</center>
</td>
<td><strong>{{ service.name }}</strong></td>
<td><strong>{{ component.name }}</strong></td>
<td>
{% if service.is_enabled %}
{% if component.is_enabled %}
<span class='label label-success'>
{% trans "Enabled" %}</span>
{% else %}
@ -67,19 +67,19 @@
{% endif %}
</td>
</tr>
{% for port in service.ports_details %}
<tr class="collapse out {{service.service_id}}"
{% for port in component.ports_details %}
<tr class="collapse out {{component.component_id}}"
style="background-color: #f9f9f9" >
<td></td>
<td class='cell-indented'><em>{{ port.name }}</em> ({{ port.details }})</td>
<td>
{% if port.name in internal_enabled_services and port.name in external_enabled_services %}
{% if port.name in internal_enabled_ports and port.name in external_enabled_ports %}
<span class='label label-success'>
{% trans "Permitted" %}</span>
{% elif port.name in internal_enabled_services %}
{% elif port.name in internal_enabled_ports %}
<span class='label label-warning'>
{% trans "Permitted (internal only)" %}</span>
{% elif port.name in external_enabled_services %}
{% elif port.name in external_enabled_ports %}
<span class='label label-warning'>
{% trans "Permitted (external only)" %}</span>
{% else %}

View File

@ -0,0 +1,139 @@
#
# 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/>.
#
"""
Tests for firewall app component.
"""
from unittest.mock import call, patch
import pytest
from plinth.modules.firewall.components import Firewall
@pytest.fixture(name='empty_firewall_list', autouse=True)
def fixture_empty_firewall_list():
"""Remove all entries in firewall list before starting a test."""
Firewall._all_firewall_components = {}
def test_init_without_arguments():
"""Test initializing the component without arguments."""
with pytest.raises(ValueError):
Firewall(None)
firewall = Firewall('test-component')
assert firewall.component_id == 'test-component'
assert firewall.name is None
assert firewall.ports == []
assert not firewall.is_external
assert len(Firewall._all_firewall_components.items()) == 1
assert Firewall._all_firewall_components['test-component'] == firewall
def test_init():
"""Test initializing the component."""
firewall = Firewall('test-component', 'test-name',
['test-port1', 'test-port2'], is_external=True)
assert firewall.name == 'test-name'
assert firewall.ports == ['test-port1', 'test-port2']
assert firewall.is_external
@patch('plinth.modules.firewall.get_port_details')
def test_port_details(get_port_details):
"""Test retrieving port details for a firewall component."""
return_values = {'test-port1': '1234/tcp', 'test-port2': '5678/udp'}
def get_port_details_side_effect(port):
return return_values[port]
get_port_details.side_effect = get_port_details_side_effect
firewall = Firewall('test-component', ports=['test-port1', 'test-port2'])
assert firewall.ports_details == [{
'name': 'test-port1',
'details': '1234/tcp'
}, {
'name': 'test-port2',
'details': '5678/udp'
}]
@patch('plinth.modules.firewall.add_service')
@patch('plinth.modules.firewall.get_enabled_services')
def test_enable(get_enabled_services, add_service):
"""Test enabling a firewall component."""
def get_enabled_services_side_effect(zone):
return {'internal': ['test-port1'], 'external': ['test-port2']}[zone]
get_enabled_services.side_effect = get_enabled_services_side_effect
# Internal
firewall = Firewall('test-firewall-1', ports=['test-port1', 'test-port2'],
is_external=False)
firewall.enable()
calls = [call('test-port2', zone='internal')]
add_service.assert_has_calls(calls)
# External
add_service.reset_mock()
firewall = Firewall('test-firewall-2', ports=['test-port1', 'test-port2'],
is_external=True)
firewall.enable()
calls = [
call('test-port1', zone='external'),
call('test-port2', zone='internal')
]
add_service.assert_has_calls(calls)
@patch('plinth.modules.firewall.remove_service')
@patch('plinth.modules.firewall.add_service')
@patch('plinth.modules.firewall.get_enabled_services')
def test_disable(get_enabled_services, add_service, remove_service):
"""Test disabling a firewall component."""
Firewall('firewall-1', ports=['test-port1'], is_external=False)
Firewall('firewall-2', ports=['test-port2'], is_external=False).enable()
Firewall('firewall-3', ports=['test-port4'], is_external=True)
Firewall('firewall-4', ports=['test-port5'], is_external=True).enable()
def get_enabled_services_side_effect(zone):
return {
'internal': ['test-port1', 'test-port2'],
'external': ['test-port4', 'test-port5']
}[zone]
get_enabled_services.side_effect = get_enabled_services_side_effect
all_ports = [
'test-port1', 'test-port2', 'test-port3', 'test-port4', 'test-port5',
'test-port6'
]
# Internal
firewall = Firewall('test-firewall-1', ports=all_ports, is_external=False)
firewall.disable()
calls = [call('test-port1', zone='internal')]
remove_service.assert_has_calls(calls)
# External
remove_service.reset_mock()
firewall = Firewall('test-firewall-2', ports=all_ports, is_external=True)
firewall.disable()
calls = [
call('test-port1', zone='internal'),
call('test-port4', zone='external')
]
remove_service.assert_has_calls(calls)

View File

@ -23,6 +23,8 @@ from django.template.response import TemplateResponse
import plinth.service as service_module
from plinth.modules import firewall
from . import components
def index(request):
"""Serve introduction page"""
@ -34,15 +36,15 @@ def index(request):
'firewall_status': 'not_running'
})
internal_enabled_services = firewall.get_enabled_services(zone='internal')
external_enabled_services = firewall.get_enabled_services(zone='external')
internal_enabled_ports = firewall.get_enabled_services(zone='internal')
external_enabled_ports = firewall.get_enabled_services(zone='external')
return TemplateResponse(
request, 'firewall.html', {
'title': firewall.name,
'description': firewall.description,
'services': list(service_module.services.values()),
'components': components.Firewall.list(),
'manual_page': firewall.manual_page,
'internal_enabled_services': internal_enabled_services,
'external_enabled_services': external_enabled_services
'internal_enabled_ports': internal_enabled_ports,
'external_enabled_ports': external_enabled_ports
})

View File

@ -24,6 +24,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.modules.i2p.resources import FAVORITES
from plinth.modules.users import register_group
@ -57,7 +58,6 @@ clients = clients
group = ('i2p', _('Manage I2P application'))
service = None
proxies_service = None
manual_page = 'I2P'
@ -92,6 +92,15 @@ class I2PApp(app_module.App):
allowed_groups=[group[0]])
self.add(shortcut)
firewall = Firewall('firewall-i2p-web', name, ports=['http', 'https'],
is_external=True)
self.add(firewall)
firewall = Firewall('firewall-i2p-proxies', name,
ports=tunnels_to_manage.values(),
is_external=False)
self.add(firewall)
def init():
"""Intialize the module."""
@ -99,18 +108,12 @@ def init():
app = I2PApp()
register_group(group)
global service, proxies_service
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
disable=disable,
is_running=is_running)
proxies_service = service_module.Service(
'i2p-proxies', name, ports=tunnels_to_manage.values(),
is_external=False, is_enabled=is_enabled, is_running=is_running)
service = service_module.Service(
managed_services[0], name, is_enabled=is_enabled, enable=enable,
disable=disable, is_running=is_running)
if is_enabled():
app.set_enabled(True)
@ -144,19 +147,12 @@ def setup(helper, old_version=None):
'--value', '0.0.0.0'
])
helper.call('post', enable)
global service, proxies_service
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
disable=disable,
is_running=is_running)
proxies_service = service_module.Service(
'i2p-proxies', name, ports=tunnels_to_manage.values(),
is_external=False, is_enabled=is_enabled, is_running=is_running)
service = service_module.Service(
managed_services[0], name, is_enabled=is_enabled, enable=enable,
disable=disable, is_running=is_running)
helper.call('post', service.notify_enabled, None, True)
helper.call('post', proxies_service.notify_enabled, None, True)
helper.call('post', app.enable)

View File

@ -25,6 +25,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import cfg, frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.modules.users import register_group
from plinth.utils import format_lazy
@ -83,6 +84,10 @@ class IkiwikiApp(app_module.App):
for site in sites:
self.add_shortcut(site)
firewall = Firewall('firewall-ikiwiki', name, ports=['http', 'https'],
is_external=True)
self.add(firewall)
def add_shortcut(self, site):
"""Add an ikiwiki shortcut to frontpage."""
shortcut = frontpage.Shortcut('shortcut-ikiwiki-' + site, site,
@ -106,9 +111,9 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(
'ikiwiki', name, ports=['http', 'https'], is_external=True,
is_enabled=is_enabled, enable=enable, disable=disable)
service = service_module.Service('ikiwiki', name,
is_enabled=is_enabled, enable=enable,
disable=disable)
if is_enabled():
app.set_enabled(True)
@ -119,10 +124,9 @@ def setup(helper, old_version=None):
helper.call('post', actions.superuser_run, 'ikiwiki', ['setup'])
global service
if service is None:
service = service_module.Service(
'ikiwiki', name, ports=['http', 'https'], is_external=True,
is_enabled=is_enabled, enable=enable, disable=disable)
helper.call('post', service.notify_enabled, None, True)
service = service_module.Service('ikiwiki', name,
is_enabled=is_enabled, enable=enable,
disable=disable)
helper.call('post', app.enable)

View File

@ -25,6 +25,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import cfg, frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.utils import format_lazy
from plinth.views import ServiceView
@ -76,6 +77,10 @@ class InfinotedApp(app_module.App):
login_required=False)
self.add(shortcut)
firewall = Firewall('firewall-infinoted', name,
ports=['infinoted-plinth'], is_external=True)
self.add(firewall)
def init():
"""Initialize the infinoted module."""
@ -85,9 +90,8 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name, ports=[
'infinoted-plinth'
], is_external=True, enable=enable, disable=disable)
service = service_module.Service(managed_services[0], name,
enable=enable, disable=disable)
if service.is_enabled():
app.set_enabled(True)
@ -106,11 +110,9 @@ def setup(helper, old_version=None):
helper.call('post', actions.superuser_run, 'infinoted', ['setup'])
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'infinoted-plinth'
], is_external=True, enable=enable, disable=disable)
service = service_module.Service(managed_services[0], name,
enable=enable, disable=disable)
helper.call('post', service.notify_enabled, None, True)
helper.call('post', app.enable)

View File

@ -26,6 +26,7 @@ from django.utils.translation import ugettext_lazy as _
from plinth import app as app_module
from plinth import frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from .manifest import backup, clients
@ -66,6 +67,10 @@ class JSXCApp(app_module.App):
icon='jsxc', url=reverse_lazy('jsxc:jsxc'), clients=clients)
self.add(shortcut)
firewall = Firewall('firewall-jsxc', name, ports=['http', 'https'],
is_external=True)
self.add(firewall)
def init():
"""Initialize the JSXC module"""
@ -75,9 +80,8 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(
'jsxc', name, ports=['http', 'https'], is_external=True,
is_enabled=is_enabled, enable=enable, disable=disable)
service = service_module.Service('jsxc', name, is_enabled=is_enabled,
enable=enable, disable=disable)
if is_enabled():
app.set_enabled(True)
@ -88,9 +92,8 @@ def setup(helper, old_version=None):
global service
if not service:
service = service_module.Service(
'jsxc', name, ports=['http', 'https'], is_external=True,
is_enabled=is_enabled, enable=enable, disable=disable)
service = service_module.Service('jsxc', name, is_enabled=is_enabled,
enable=enable, disable=disable)
helper.call('post', app.enable)

View File

@ -29,6 +29,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from .manifest import backup, clients
@ -91,6 +92,10 @@ class MatrixSynapseApp(app_module.App):
login_required=True)
self.add(shortcut)
firewall = Firewall('firewall-matrixsynapse', name,
ports=['matrix-synapse-plinth'], is_external=True)
self.add(firewall)
def init():
"""Initialize the matrix-synapse module."""
@ -100,9 +105,8 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service('matrix-synapse', name, ports=[
'matrix-synapse-plinth'
], is_external=True, is_enabled=is_enabled, enable=enable,
service = service_module.Service('matrix-synapse', name,
is_enabled=is_enabled, enable=enable,
disable=disable)
if is_enabled():
app.set_enabled(True)
@ -113,14 +117,12 @@ def setup(helper, old_version=None):
helper.install(managed_packages)
global service
if service is None:
service = service_module.Service('matrix-synapse', name, ports=[
'matrix-synapse-plinth'
], is_external=True, is_enabled=is_enabled, enable=enable,
service = service_module.Service('matrix-synapse', name,
is_enabled=is_enabled, enable=enable,
disable=disable)
helper.call('post', actions.superuser_run, 'matrixsynapse',
['post-install'])
helper.call('post', service.notify_enabled, None, True)
helper.call('post', app.enable)

View File

@ -24,6 +24,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from .manifest import backup, clients
@ -78,6 +79,10 @@ class MediaWikiApp(app_module.App):
clients=clients, login_required=True)
self.add(shortcut)
firewall = Firewall('firewall-mediawiki', name,
ports=['http', 'https'], is_external=True)
self.add(firewall)
class Shortcut(frontpage.Shortcut):
"""Frontpage shortcut for only logged users when in private mode."""
@ -96,9 +101,9 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(
'mediawiki', name, ports=['http', 'https'], is_external=True,
is_enabled=is_enabled, enable=enable, disable=disable)
service = service_module.Service('mediawiki', name,
is_enabled=is_enabled, enable=enable,
disable=disable)
if is_enabled():
app.set_enabled(True)
@ -111,16 +116,9 @@ def setup(helper, old_version=None):
helper.call('enable', actions.superuser_run, 'mediawiki', ['enable'])
global service
if service is None:
service = service_module.Service(
'mediawiki',
name,
is_external=True,
is_enabled=is_enabled,
enable=enable,
disable=disable,
ports=['http', 'https'],
)
helper.call('post', service.notify_enabled, None, True)
service = service_module.Service('mediawiki', name,
is_enabled=is_enabled, enable=enable,
disable=disable)
helper.call('post', app.enable)

View File

@ -26,6 +26,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import cfg, frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.utils import format_lazy
from .manifest import backup, clients
@ -95,6 +96,10 @@ class MinetestApp(app_module.App):
login_required=False)
self.add(shortcut)
firewall = Firewall('firewall-minetest', name,
ports=['minetest-plinth'], is_external=True)
self.add(firewall)
def init():
"""Initialize the module."""
@ -104,9 +109,8 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name, ports=[
'minetest-plinth'
], is_external=True, enable=enable, disable=disable)
service = service_module.Service(managed_services[0], name,
enable=enable, disable=disable)
if service.is_enabled():
app.set_enabled(True)
@ -116,10 +120,8 @@ def setup(helper, old_version=None):
helper.install(managed_packages)
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'minetest-plinth'
], is_external=True, enable=enable, disable=disable)
helper.call('post', service.notify_enabled, None, True)
service = service_module.Service(managed_services[0], name,
enable=enable, disable=disable)
helper.call('post', app.enable)

View File

@ -24,6 +24,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import cfg, frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.modules.users import register_group
from plinth.utils import format_lazy
@ -82,6 +83,11 @@ class MLDonkeyApp(app_module.App):
clients=clients, allowed_groups=[group[0]])
self.add(shortcuts)
firewall = Firewall('firewall-mldonkey', name,
ports=['http', 'https'], is_external=True)
self.add(firewall)
def init():
"""Initialize the MLDonkey module."""
@ -92,11 +98,9 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
disable=disable,
is_running=is_running)
service = service_module.Service(
managed_services[0], name, is_enabled=is_enabled, enable=enable,
disable=disable, is_running=is_running)
if is_enabled():
app.set_enabled(True)
@ -109,12 +113,9 @@ def setup(helper, old_version=None):
helper.call('post', actions.superuser_run, 'mldonkey', ['enable'])
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
disable=disable,
is_running=is_running)
helper.call('post', service.notify_enabled, None, True)
service = service_module.Service(
managed_services[0], name, is_enabled=is_enabled, enable=enable,
disable=disable, is_running=is_running)
helper.call('post', app.enable)

View File

@ -25,6 +25,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.views import ServiceView
from .manifest import backup, clients
@ -79,6 +80,10 @@ class MumbleApp(app_module.App):
configure_url=reverse_lazy('mumble:index'), clients=clients)
self.add(shortcut)
firewall = Firewall('firewall-mumble', name, ports=['mumble-plinth'],
is_external=True)
self.add(firewall)
def init():
"""Intialize the Mumble module."""
@ -88,9 +93,8 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name, ports=[
'mumble-plinth'
], is_external=True, enable=enable, disable=disable)
service = service_module.Service(managed_services[0], name,
enable=enable, disable=disable)
if service.is_enabled():
app.set_enabled(True)
@ -110,10 +114,8 @@ def setup(helper, old_version=None):
helper.install(managed_packages)
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'mumble-plinth'
], is_external=True, enable=enable, disable=disable)
helper.call('post', service.notify_enabled, None, True)
service = service_module.Service(managed_services[0], name,
enable=enable, disable=disable)
helper.call('post', app.enable)

View File

@ -25,6 +25,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import cfg, frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.utils import format_lazy
from .manifest import backup
@ -80,6 +81,10 @@ class OpenVPNApp(app_module.App):
configure_url=reverse_lazy('openvpn:index'), login_required=True)
self.add(shortcut)
firewall = Firewall('firewall-openvpn', name, ports=['openvpn'],
is_external=True)
self.add(firewall)
def init():
"""Initialize the OpenVPN module."""
@ -89,8 +94,7 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name,
ports=['openvpn'], is_external=True)
service = service_module.Service(managed_services[0], name)
if service.is_enabled() and is_setup():
app.set_enabled(True)
@ -103,7 +107,6 @@ def setup(helper, old_version=None):
global service
if service is None:
service = service_module.Service(managed_services[0], name,
ports=['openvpn'], is_external=True,
enable=enable, disable=disable)
if service.is_enabled() and is_setup():

View File

@ -70,8 +70,6 @@ def index(request):
@require_POST
def setup(request):
"""Start the setup process."""
openvpn.service.notify_enabled(None, True)
global setup_process
if not openvpn.is_setup() and not setup_process:
setup_process = actions.superuser_run('openvpn', ['setup'],

View File

@ -25,6 +25,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import cfg, frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.utils import format_lazy
from plinth.views import ServiceView
@ -83,6 +84,10 @@ class PrivoxyApp(app_module.App):
configure_url=reverse_lazy('privoxy:index'), login_required=True)
self.add(shortcut)
firewall = Firewall('firewall-privoxy', name, ports=['privoxy'],
is_external=False)
self.add(firewall)
def init():
"""Intialize the module."""
@ -93,7 +98,6 @@ def init():
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name,
ports=['privoxy'], is_external=False,
enable=enable, disable=disable)
if service.is_enabled():
@ -107,9 +111,7 @@ def setup(helper, old_version=None):
global service
if service is None:
service = service_module.Service(managed_services[0], name,
ports=['privoxy'], is_external=False,
enable=enable, disable=disable)
helper.call('post', service.notify_enabled, None, True)
helper.call('post', app.enable)

View File

@ -25,6 +25,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import cfg, frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.utils import format_lazy
from plinth.views import ServiceView
@ -87,6 +88,10 @@ class QuasselApp(app_module.App):
login_required=True)
self.add(shortcut)
firewall = Firewall('firewall-quassel', name,
ports=['quassel-plinth'], is_external=True)
self.add(firewall)
def init():
"""Initialize the quassel module."""
@ -96,9 +101,8 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name, ports=[
'quassel-plinth'
], is_external=True, enable=enable, disable=disable)
service = service_module.Service(managed_services[0], name,
enable=enable, disable=disable)
if service.is_enabled():
app.set_enabled(True)
@ -118,10 +122,8 @@ def setup(helper, old_version=None):
helper.install(managed_packages)
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'quassel-plinth'
], is_external=True, enable=enable, disable=disable)
helper.call('post', service.notify_enabled, None, True)
service = service_module.Service(managed_services[0], name,
enable=enable, disable=disable)
helper.call('post', app.enable)

View File

@ -30,6 +30,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import cfg, frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.utils import format_lazy
from .manifest import backup, clients
@ -90,6 +91,10 @@ class RadicaleApp(app_module.App):
clients=clients, login_required=True)
self.add(shortcut)
firewall = Firewall('firewall-radicale', name,
ports=['http', 'https'], is_external=True)
self.add(firewall)
def init():
"""Initialize the radicale module."""
@ -99,11 +104,9 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
disable=disable,
is_running=is_running)
service = service_module.Service(
managed_services[0], name, is_enabled=is_enabled, enable=enable,
disable=disable, is_running=is_running)
if is_enabled():
app.set_enabled(True)
@ -137,12 +140,9 @@ def setup(helper, old_version=None):
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
disable=disable,
is_running=is_running)
helper.call('post', service.notify_enabled, None, True)
service = service_module.Service(
managed_services[0], name, is_enabled=is_enabled, enable=enable,
disable=disable, is_running=is_running)
helper.call('post', app.enable)

View File

@ -25,6 +25,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.views import ServiceView
from .manifest import backup, clients
@ -88,6 +89,11 @@ class ReproApp(app_module.App):
login_required=True)
self.add(shortcut)
firewall = Firewall('firewall-repro', name,
ports=['sip', 'sips',
'rtp-plinth'], is_external=True)
self.add(firewall)
def init():
"""Initialize the repro module."""
@ -97,9 +103,8 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name, ports=[
'sip', 'sips', 'rtp-plinth'
], is_external=True, enable=enable, disable=disable)
service = service_module.Service(managed_services[0], name,
enable=enable, disable=disable)
if service.is_enabled():
app.set_enabled(True)
@ -120,10 +125,8 @@ def setup(helper, old_version=None):
helper.call('post', actions.superuser_run, 'repro', ['setup'])
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'sip', 'sips', 'rtp-plinth'
], is_external=True, enable=enable, disable=disable)
helper.call('post', service.notify_enabled, None, True)
service = service_module.Service(managed_services[0], name,
enable=enable, disable=disable)
helper.call('post', app.enable)

View File

@ -23,6 +23,7 @@ from django.utils.translation import ugettext_lazy as _
from plinth import app as app_module
from plinth import cfg, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.utils import format_lazy
from .manifest import clients
@ -69,6 +70,10 @@ class RestoreApp(app_module.App):
parent_url_name='apps')
self.add(menu_item)
firewall = Firewall('firewall-restore', name, ports=['http', 'https'],
is_external=True)
self.add(firewall)
def init():
"""Initialize the reStore module."""
@ -78,9 +83,7 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name,
ports=['http',
'https'], is_external=False)
service = service_module.Service(managed_services[0], name)
def setup(helper, old_version=None):
@ -88,6 +91,4 @@ def setup(helper, old_version=None):
helper.install(managed_packages)
global service
if service is None:
service = service_module.Service(managed_services[0], name,
ports=['http',
'https'], is_external=False)
service = service_module.Service(managed_services[0], name)

View File

@ -24,6 +24,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from .manifest import backup, clients
@ -81,6 +82,10 @@ class RoundcubeApp(app_module.App):
clients=clients, login_required=True)
self.add(shortcut)
firewall = Firewall('firewall-roundcube', name,
ports=['http', 'https'], is_external=True)
self.add(firewall)
def init():
"""Intialize the module."""
@ -90,9 +95,9 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(
'roundcube', name, ports=['http', 'https'], is_external=True,
is_enabled=is_enabled, enable=enable, disable=disable)
service = service_module.Service('roundcube', name,
is_enabled=is_enabled, enable=enable,
disable=disable)
if is_enabled():
app.set_enabled(True)
@ -105,9 +110,9 @@ def setup(helper, old_version=None):
helper.call('post', actions.superuser_run, 'roundcube', ['setup'])
global service
if service is None:
service = service_module.Service(
'roundcube', name, ports=['http', 'https'], is_external=True,
is_enabled=is_enabled, enable=enable, disable=disable)
service = service_module.Service('roundcube', name,
is_enabled=is_enabled, enable=enable,
disable=disable)
helper.call('post', app.enable)

View File

@ -26,6 +26,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.modules.users import register_group
from .manifest import PUBLIC_ACCESS_SETTING_FILE, backup, clients
@ -75,6 +76,10 @@ class SearxApp(app_module.App):
allowed_groups=[group[0]])
self.add(shortcut)
firewall = Firewall('firewall-searx', name, ports=['http', 'https'],
is_external=True)
self.add(firewall)
def set_shortcut_login_required(self, login_required):
"""Change the login_required property of shortcut."""
shortcut = self.remove('shortcut-searx')
@ -91,9 +96,8 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
service = service_module.Service(managed_services[0], name,
is_enabled=is_enabled, enable=enable,
disable=disable)
if is_enabled():
@ -113,9 +117,8 @@ def setup(helper, old_version=None):
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
service = service_module.Service(managed_services[0], name,
is_enabled=is_enabled, enable=enable,
disable=disable)
helper.call('post', app.enable)

View File

@ -24,6 +24,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from .manifest import clients
@ -69,6 +70,10 @@ class ShaarliApp(app_module.App):
clients=clients, login_required=True)
self.add(shortcut)
firewall = Firewall('firewall-shaarli', name, ports=['http', 'https'],
is_external=True)
self.add(firewall)
def init():
"""Initialize the module."""
@ -78,9 +83,9 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(
'shaarli', name, ports=['http', 'https'], is_external=True,
is_enabled=is_enabled, enable=enable, disable=disable)
service = service_module.Service('shaarli', name,
is_enabled=is_enabled, enable=enable,
disable=disable)
if is_enabled():
app.set_enabled(True)
@ -91,10 +96,9 @@ def setup(helper, old_version=None):
helper.install(managed_packages)
global service
if service is None:
service = service_module.Service(
'shaarli', name, ports=['http', 'https'], is_external=True,
is_enabled=is_enabled, enable=enable, disable=disable)
helper.call('post', service.notify_enabled, None, True)
service = service_module.Service('shaarli', name,
is_enabled=is_enabled, enable=enable,
disable=disable)
helper.call('post', app.enable)

View File

@ -25,6 +25,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import cfg, frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.utils import format_lazy
from .manifest import backup
@ -78,6 +79,11 @@ class ShadowsocksApp(app_module.App):
login_required=True)
self.add(shortcut)
firewall = Firewall('firewall-shadowsocks', name,
ports=['shadowsocks-local-plinth'],
is_external=False)
self.add(firewall)
def init():
"""Intialize the module."""
@ -87,10 +93,9 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service('shadowsocks', name, ports=[
'shadowsocks-local-plinth'
], is_external=False, is_enabled=is_enabled, is_running=is_running,
enable=enable, disable=disable)
service = service_module.Service(
'shadowsocks', name, is_enabled=is_enabled, is_running=is_running,
enable=enable, disable=disable)
if service.is_enabled():
app.set_enabled(True)
@ -102,10 +107,9 @@ def setup(helper, old_version=None):
helper.call('post', actions.superuser_run, 'shadowsocks', ['setup'])
global service
if service is None:
service = service_module.Service('shadowsocks', name, ports=[
'shadowsocks-local-plinth'
], is_external=False, is_enabled=is_enabled, is_running=is_running,
enable=enable, disable=disable)
service = service_module.Service(
'shadowsocks', name, is_enabled=is_enabled, is_running=is_running,
enable=enable, disable=disable)
helper.call('post', app.enable)

View File

@ -22,8 +22,9 @@ from django.utils.translation import ugettext_lazy as _
from plinth import actions
from plinth import app as app_module
from plinth import cfg, menu
from plinth import menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.views import ServiceView
from .manifest import backup
@ -62,6 +63,10 @@ class SSHApp(app_module.App):
'ssh:index', parent_url_name='system')
self.add(menu_item)
firewall = Firewall('firewall-ssh', name, ports=['ssh'],
is_external=True)
self.add(firewall)
def init():
"""Intialize the ssh module."""
@ -70,8 +75,7 @@ def init():
app.set_enabled(True)
global service
service = service_module.Service(managed_services[0], name, ports=['ssh'],
is_external=True)
service = service_module.Service(managed_services[0], name)
def setup(helper, old_version=None):

View File

@ -298,10 +298,8 @@ def setup(helper, old_version=None):
global service
if service is None:
service = service_module.Service(
managed_services[0], name, ports=[], is_external=True,
is_enabled=is_enabled, enable=enable, disable=disable,
is_running=is_running)
helper.call('post', service.notify_enabled, None, True)
managed_services[0], name, is_enabled=is_enabled, enable=enable,
disable=disable, is_running=is_running)
disks = get_disks()
root_device = get_root_device(disks)
if is_expandable(root_device):

View File

@ -24,6 +24,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import cfg, frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.modules.users import register_group
from plinth.utils import format_lazy
@ -85,6 +86,10 @@ class SyncthingApp(app_module.App):
login_required=True, allowed_groups=[group[0]])
self.add(shortcut)
firewall = Firewall('firewall-syncthing', name,
ports=['http', 'https'], is_external=True)
self.add(firewall)
def init():
"""Intialize the module."""
@ -95,11 +100,9 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
disable=disable,
is_running=is_running)
service = service_module.Service(
managed_services[0], name, is_enabled=is_enabled, enable=enable,
disable=disable, is_running=is_running)
if is_enabled():
app.set_enabled(True)
@ -111,12 +114,9 @@ def setup(helper, old_version=None):
helper.call('post', actions.superuser_run, 'syncthing', ['enable'])
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
disable=disable,
is_running=is_running)
helper.call('post', service.notify_enabled, None, True)
service = service_module.Service(
managed_services[0], name, is_enabled=is_enabled, enable=enable,
disable=disable, is_running=is_running)
helper.call('post', app.enable)

View File

@ -27,6 +27,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import cfg, frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.utils import format_lazy
from .errors import TahoeConfigurationError
@ -77,6 +78,10 @@ class TahoeApp(app_module.App):
icon='tahoe-lafs', url=None, login_required=True)
self.add(shortcut)
firewall = Firewall('firewall-tahoe', name, ports=['tahoe-plinth'],
is_external=True)
self.add(firewall)
class Shortcut(frontpage.Shortcut):
"""Frontpage shortcut to use configured domain name for URL."""
@ -123,11 +128,9 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup' and is_setup():
service = service_module.Service(managed_services[0], name, ports=[
'tahoe-plinth'
], is_external=True, is_enabled=is_enabled, enable=enable,
disable=disable,
is_running=is_running)
service = service_module.Service(
managed_services[0], name, is_enabled=is_enabled, enable=enable,
disable=disable, is_running=is_running)
if is_enabled():
app.set_enabled(True)
@ -151,12 +154,9 @@ def post_setup(configured_domain_name):
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'tahoe-plinth'
], is_external=True, is_enabled=is_enabled, enable=enable,
disable=disable,
is_running=is_running)
service.notify_enabled(None, True)
service = service_module.Service(
managed_services[0], name, is_enabled=is_enabled, enable=enable,
disable=disable, is_running=is_running)
app.enable()

View File

@ -26,6 +26,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.modules.names import SERVICES
from plinth.signals import domain_added, domain_removed
@ -75,6 +76,15 @@ class TorApp(app_module.App):
'tor:index', parent_url_name='apps')
self.add(menu_item)
firewall = Firewall('firewall-tor-socks', _('Tor Socks Proxy'),
ports=['tor-socks'], is_external=False)
self.add(firewall)
firewall = Firewall('firewall-tor-relay', _('Tor Bridge Relay'),
ports=['tor-orport', 'tor-obfs3',
'tor-obfs4'], is_external=True)
self.add(firewall)
def init():
"""Initialize the module."""
@ -90,15 +100,14 @@ def init():
global socks_service
socks_service = service_module.Service(
'tor-socks', _('Tor Socks Proxy'), ports=['tor-socks'],
is_external=False, is_enabled=utils.is_enabled,
'tor-socks', _('Tor Socks Proxy'), is_enabled=utils.is_enabled,
is_running=utils.is_running)
global bridge_service
bridge_service = service_module.Service(
'tor-bridge', _('Tor Bridge Relay'),
ports=['tor-orport', 'tor-obfs3', 'tor-obfs4'], is_external=True,
is_enabled=utils.is_enabled, is_running=utils.is_running)
bridge_service = service_module.Service('tor-bridge',
_('Tor Bridge Relay'),
is_enabled=utils.is_enabled,
is_running=utils.is_running)
# Register hidden service name with Name Services module.
status = utils.get_status()
@ -132,23 +141,17 @@ def setup(helper, old_version=None):
global socks_service
if socks_service is None:
socks_service = service_module.Service(
'tor-socks', _('Tor Anonymity Network'), ports=['tor-socks'],
is_external=False, is_enabled=utils.is_enabled,
is_running=utils.is_running)
if not old_version:
helper.call('post', socks_service.notify_enabled, None, True)
socks_service = service_module.Service('tor-socks',
_('Tor Anonymity Network'),
is_enabled=utils.is_enabled,
is_running=utils.is_running)
global bridge_service
if bridge_service is None:
bridge_service = service_module.Service(
'tor-bridge', _('Tor Bridge Relay'),
ports=['tor-orport', 'tor-obfs3', 'tor-obfs4'], is_external=True,
is_enabled=utils.is_enabled, is_running=utils.is_running)
if not old_version:
helper.call('post', bridge_service.notify_enabled, None, True)
bridge_service = service_module.Service('tor-bridge',
_('Tor Bridge Relay'),
is_enabled=utils.is_enabled,
is_running=utils.is_running)
helper.call('post', update_hidden_service_domain)
helper.call('post', app.enable)

View File

@ -160,8 +160,6 @@ def _collect_config_result(request):
status = tor_utils.get_status()
tor.socks_service.notify_enabled(None, status['enabled'])
tor.bridge_service.notify_enabled(None, status['enabled'])
tor.update_hidden_service_domain(status)
if not return_code:

View File

@ -26,6 +26,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.modules.users import register_group
from .manifest import backup, clients
@ -77,6 +78,10 @@ class TransmissionApp(app_module.App):
login_required=True, allowed_groups=[group[0]])
self.add(shortcut)
firewall = Firewall('firewall-transmission', name,
ports=['http', 'https'], is_external=True)
self.add(firewall)
def init():
"""Initialize the Transmission module."""
@ -87,9 +92,8 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
service = service_module.Service(managed_services[0], name,
is_enabled=is_enabled, enable=enable,
disable=disable)
if is_enabled():
@ -111,11 +115,9 @@ def setup(helper, old_version=None):
helper.call('post', actions.superuser_run, 'transmission', ['enable'])
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
service = service_module.Service(managed_services[0], name,
is_enabled=is_enabled, enable=enable,
disable=disable)
helper.call('post', service.notify_enabled, None, True)
helper.call('post', app.enable)

View File

@ -25,6 +25,7 @@ from plinth import action_utils, actions
from plinth import app as app_module
from plinth import cfg, frontpage, menu
from plinth import service as service_module
from plinth.modules.firewall.components import Firewall
from plinth.modules.users import register_group
from plinth.utils import Version, format_lazy
@ -83,6 +84,10 @@ class TTRSSApp(app_module.App):
allowed_groups=[group[0]])
self.add(shortcut)
firewall = Firewall('firewall-ttrss', name, ports=['http', 'https'],
is_external=True)
self.add(firewall)
def init():
"""Intialize the module."""
@ -93,9 +98,8 @@ def init():
global service
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
service = service_module.Service(managed_services[0], name,
is_enabled=is_enabled, enable=enable,
disable=disable)
if is_enabled():
@ -110,11 +114,9 @@ def setup(helper, old_version=None):
helper.call('post', actions.superuser_run, 'ttrss', ['enable'])
global service
if service is None:
service = service_module.Service(managed_services[0], name, ports=[
'http', 'https'
], is_external=True, is_enabled=is_enabled, enable=enable,
service = service_module.Service(managed_services[0], name,
is_enabled=is_enabled, enable=enable,
disable=disable)
helper.call('post', service.notify_enabled, None, True)
helper.call('post', app.enable)

View File

@ -64,7 +64,7 @@ def init():
app.set_enabled(True)
global service
service = service_module.Service('auto-upgrades', name, is_external=False,
service = service_module.Service('auto-upgrades', name,
is_enabled=is_enabled, enable=enable,
disable=disable)

View File

@ -20,11 +20,7 @@ Framework for working with servers and their services.
import collections
from django.utils.translation import ugettext_lazy as _
from plinth import action_utils, actions, cfg
from plinth.signals import service_enabled
from plinth.utils import format_lazy
from plinth import action_utils, actions
services = {}
@ -32,8 +28,7 @@ services = {}
class Service():
"""
Representation of an application service provided by the machine
containing information such as current status and ports required
for operation.
containing information such as current status.
- service_id: unique service name. If possible this should be the name of
the service's systemd unit file (without the extension).
@ -44,18 +39,13 @@ class Service():
- is_running (optional): Boolean or a method returning Boolean
"""
def __init__(self, service_id, name, ports=None, is_external=False,
is_enabled=None, enable=None, disable=None, is_running=None):
if ports is None:
ports = []
def __init__(self, service_id, name, is_enabled=None, enable=None,
disable=None, is_running=None):
if is_enabled is None:
is_enabled = self._default_is_enabled
self.service_id = service_id
self.name = name
self.ports = ports
self.is_external = is_external
self._is_enabled = is_enabled
self._enable = enable
self._disable = disable
@ -65,32 +55,17 @@ class Service():
assert service_id not in services
services[service_id] = self
@property
def ports_details(self):
"""Retrieve details of ports associated with service."""
from plinth.modules import firewall
ports_details = []
for port in self.ports:
ports_details.append({
'name': port,
'details': firewall.get_port_details(port),
})
return ports_details
def enable(self):
if self._enable is None:
actions.superuser_run('service', ['enable', self.service_id])
else:
self._call_or_return(self._enable)
self.notify_enabled(None, True)
def disable(self):
if self._disable is None:
actions.superuser_run('service', ['disable', self.service_id])
else:
self._call_or_return(self._disable)
self.notify_enabled(None, False)
def is_enabled(self):
"""Return whether the service is enabled."""
@ -105,11 +80,6 @@ class Service():
return self._call_or_return(self._is_running)
def notify_enabled(self, sender, enabled):
"""Notify observers about change in state of service."""
service_enabled.send_robust(sender=sender, service_id=self.service_id,
enabled=enabled)
@staticmethod
def _call_or_return(obj):
"""Calls obj if it's callable, returns it if it's Boolean."""
@ -131,16 +101,3 @@ class Service():
"""Returns a list of interfaces in a firewall zone."""
from plinth.modules import firewall
return firewall.get_interfaces('internal')
def init():
"""Register some misc. services that don't fit elsewhere."""
Service('http', _('Web Server'), ports=['http'], is_external=True,
is_enabled=True)
Service('https', _('Web Server over Secure Socket Layer'), ports=['https'],
is_external=True, is_enabled=True)
Service(
'plinth',
format_lazy(
_('{box_name} Web Interface (Plinth)'), box_name=_(cfg.box_name)),
ports=['https'], is_external=True, is_enabled=True)

View File

@ -20,7 +20,6 @@ Django signals emitted within FreedomBox.
from django.dispatch import Signal
service_enabled = Signal(providing_args=['service_id', 'enabled'])
pre_module_loading = Signal()
post_module_loading = Signal()
post_setup = Signal(providing_args=['module_name'])

View File

@ -153,6 +153,15 @@ def test_follower_component_initialization():
assert component.is_enabled()
def test_follower_component_set_enabled():
"""Test setting internal enabled state a follower component."""
component = FollowerComponent('test-follower-1', False)
component.set_enabled(True)
assert component.is_enabled()
component.set_enabled(False)
assert not component.is_enabled()
def test_follower_component_enable():
"""Test enabling a follower component."""
component = FollowerComponent('test-follower-1', False)