mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-05-20 10:34:30 +00:00
Name Services module
This commit is contained in:
parent
5dfa2d0626
commit
e0bfd1401f
1
data/etc/plinth/modules-enabled/names
Normal file
1
data/etc/plinth/modules-enabled/names
Normal file
@ -0,0 +1 @@
|
|||||||
|
plinth.modules.names
|
||||||
@ -24,4 +24,6 @@ from .config import init
|
|||||||
|
|
||||||
__all__ = ['config', 'init']
|
__all__ = ['config', 'init']
|
||||||
|
|
||||||
depends = ['plinth.modules.system']
|
depends = ['plinth.modules.system',
|
||||||
|
'plinth.modules.firewall',
|
||||||
|
'plinth.modules.names']
|
||||||
|
|||||||
@ -33,8 +33,11 @@ import socket
|
|||||||
|
|
||||||
from plinth import actions
|
from plinth import actions
|
||||||
from plinth import cfg
|
from plinth import cfg
|
||||||
|
from plinth.modules.firewall import firewall
|
||||||
|
from plinth.modules.names import SERVICES
|
||||||
from plinth.signals import pre_hostname_change, post_hostname_change
|
from plinth.signals import pre_hostname_change, post_hostname_change
|
||||||
from plinth.signals import domainname_change
|
from plinth.signals import domainname_change
|
||||||
|
from plinth.signals import domain_added, domain_removed
|
||||||
|
|
||||||
|
|
||||||
HOSTNAME_REGEX = r'^[a-zA-Z0-9]([-a-zA-Z0-9]{,61}[a-zA-Z0-9])?$'
|
HOSTNAME_REGEX = r'^[a-zA-Z0-9]([-a-zA-Z0-9]{,61}[a-zA-Z0-9])?$'
|
||||||
@ -132,6 +135,23 @@ def init():
|
|||||||
menu.add_urlname(ugettext_lazy('Configure'), 'glyphicon-cog',
|
menu.add_urlname(ugettext_lazy('Configure'), 'glyphicon-cog',
|
||||||
'config:index', 10)
|
'config:index', 10)
|
||||||
|
|
||||||
|
# Register domain with Name Services module.
|
||||||
|
domainname = get_domainname()
|
||||||
|
if domainname:
|
||||||
|
try:
|
||||||
|
domainname_services = firewall.get_enabled_services(
|
||||||
|
zone='external')
|
||||||
|
except actions.ActionError:
|
||||||
|
# This happens when firewalld is not installed.
|
||||||
|
# TODO: Are these services actually enabled?
|
||||||
|
domainname_services = [service[0] for service in SERVICES]
|
||||||
|
else:
|
||||||
|
domainname_services = None
|
||||||
|
|
||||||
|
domain_added.send_robust(sender='config', domain_type='domainname',
|
||||||
|
name=domainname, description=_('Domain Name'),
|
||||||
|
services=domainname_services)
|
||||||
|
|
||||||
|
|
||||||
def index(request):
|
def index(request):
|
||||||
"""Serve the configuration form"""
|
"""Serve the configuration form"""
|
||||||
@ -228,3 +248,18 @@ def set_domainname(domainname):
|
|||||||
domainname_change.send_robust(sender='config',
|
domainname_change.send_robust(sender='config',
|
||||||
old_domainname=old_domainname,
|
old_domainname=old_domainname,
|
||||||
new_domainname=domainname)
|
new_domainname=domainname)
|
||||||
|
|
||||||
|
# Update domain registered with Name Services module.
|
||||||
|
domain_removed.send_robust(sender='config', domain_type='domainname')
|
||||||
|
if domainname:
|
||||||
|
try:
|
||||||
|
domainname_services = firewall.get_enabled_services(
|
||||||
|
zone='external')
|
||||||
|
except actions.ActionError:
|
||||||
|
# This happens when firewalld is not installed.
|
||||||
|
# TODO: Are these services actually enabled?
|
||||||
|
domainname_services = [service[0] for service in SERVICES]
|
||||||
|
|
||||||
|
domain_added.send_robust(sender='config', domain_type='domainname',
|
||||||
|
name=domainname, description=_('Domain Name'),
|
||||||
|
services=domainname_services)
|
||||||
|
|||||||
121
plinth/modules/names/__init__.py
Normal file
121
plinth/modules/names/__init__.py
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
#
|
||||||
|
# This file is part of Plinth.
|
||||||
|
#
|
||||||
|
# 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/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
Plinth module to configure name services
|
||||||
|
"""
|
||||||
|
|
||||||
|
from gettext import gettext as _
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from plinth import cfg
|
||||||
|
from plinth.signals import domain_added, domain_removed
|
||||||
|
|
||||||
|
|
||||||
|
SERVICES = [
|
||||||
|
('http', _('HTTP'), 80),
|
||||||
|
('https', _('HTTPS'), 443),
|
||||||
|
('ssh', _('SSH'), 22),
|
||||||
|
]
|
||||||
|
|
||||||
|
depends = ['plinth.modules.system']
|
||||||
|
|
||||||
|
domain_types = {}
|
||||||
|
domains = {}
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def init():
|
||||||
|
"""Initialize the names module."""
|
||||||
|
menu = cfg.main_menu.get('system:index')
|
||||||
|
menu.add_urlname(_('Name Services'), 'glyphicon-th', 'names:index', 19)
|
||||||
|
|
||||||
|
domain_added.connect(on_domain_added)
|
||||||
|
domain_removed.connect(on_domain_removed)
|
||||||
|
|
||||||
|
|
||||||
|
def on_domain_added(sender, domain_type, name='', description='',
|
||||||
|
services=None, **kwargs):
|
||||||
|
"""Add domain to global list."""
|
||||||
|
if not domain_type:
|
||||||
|
return
|
||||||
|
domain_types[domain_type] = description
|
||||||
|
|
||||||
|
if not name:
|
||||||
|
return
|
||||||
|
if not services:
|
||||||
|
services = []
|
||||||
|
|
||||||
|
if domain_type not in domains:
|
||||||
|
# new domain_type
|
||||||
|
domains[domain_type] = {}
|
||||||
|
domains[domain_type][name] = services
|
||||||
|
logger.info('Added domain %s of type %s with services %s',
|
||||||
|
name, domain_type, str(services))
|
||||||
|
|
||||||
|
|
||||||
|
def on_domain_removed(sender, domain_type, name='', **kwargs):
|
||||||
|
"""Remove domain from global list."""
|
||||||
|
if domain_type in domains:
|
||||||
|
if name == '': # remove all domains of this type
|
||||||
|
domains[domain_type] = {}
|
||||||
|
logger.info('Removed all domains of type %s', domain_type)
|
||||||
|
elif name in domains[domain_type]:
|
||||||
|
del domains[domain_type][name]
|
||||||
|
logger.info('Removed domain %s of type %s', name, domain_type)
|
||||||
|
|
||||||
|
|
||||||
|
def get_domain_types():
|
||||||
|
"""Get list of domain_types."""
|
||||||
|
return list(domain_types.keys())
|
||||||
|
|
||||||
|
|
||||||
|
def get_description(domain_type):
|
||||||
|
"""Get description of a domain_type, if available."""
|
||||||
|
if domain_type in domain_types:
|
||||||
|
return domain_types[domain_type]
|
||||||
|
else:
|
||||||
|
return domain_type
|
||||||
|
|
||||||
|
|
||||||
|
def get_domain(domain_type):
|
||||||
|
"""
|
||||||
|
Get domain of type domain_type.
|
||||||
|
|
||||||
|
This function is meant for use with single-domain domain_types. If there is
|
||||||
|
more than one domain, any one of the domains may be returned.
|
||||||
|
"""
|
||||||
|
if domain_type in domains and len(domains[domain_type]) > 0:
|
||||||
|
return list(domains[domain_type].keys())[0]
|
||||||
|
else:
|
||||||
|
return _('Not Available')
|
||||||
|
|
||||||
|
|
||||||
|
def get_services(domain_type, domain):
|
||||||
|
"""Get list of enabled services for a domain."""
|
||||||
|
try:
|
||||||
|
return domains[domain_type][domain]
|
||||||
|
except KeyError:
|
||||||
|
# domain_type or domain not registered
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def get_services_status(domain_type, domain):
|
||||||
|
"""Get list of whether each service is enabled for a domain."""
|
||||||
|
enabled = get_services(domain_type, domain)
|
||||||
|
return [service[0] in enabled for service in SERVICES]
|
||||||
63
plinth/modules/names/templates/names.html
Normal file
63
plinth/modules/names/templates/names.html
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% comment %}
|
||||||
|
#
|
||||||
|
# This file is part of Plinth.
|
||||||
|
#
|
||||||
|
# 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/>.
|
||||||
|
#
|
||||||
|
{% endcomment %}
|
||||||
|
|
||||||
|
{% load bootstrap %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<h2>Name Services</h2>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<table class="table table-bordered table-condensed table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
{% for service in status.services %}
|
||||||
|
<td>
|
||||||
|
<div class="text-center">{{ service }}</div>
|
||||||
|
</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for name_service in status.name_services %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<b>{{ name_service.type }}</b></br>
|
||||||
|
<i>{{ name_service.name }}</i>
|
||||||
|
</td>
|
||||||
|
{% for service in name_service.services_enabled %}
|
||||||
|
<td>
|
||||||
|
{% if service %}
|
||||||
|
<span class="label label-success">Enabled</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="label label-warning">Disabled<span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
0
plinth/modules/names/tests/__init__.py
Normal file
0
plinth/modules/names/tests/__init__.py
Normal file
96
plinth/modules/names/tests/test_names.py
Normal file
96
plinth/modules/names/tests/test_names.py
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#
|
||||||
|
# This file is part of Plinth.
|
||||||
|
#
|
||||||
|
# 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 names module.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from .. import domain_types, domains
|
||||||
|
from .. import on_domain_added, on_domain_removed
|
||||||
|
from .. import get_domain_types, get_description
|
||||||
|
from .. import get_domain, get_services, get_services_status
|
||||||
|
|
||||||
|
|
||||||
|
class TestNames(unittest.TestCase):
|
||||||
|
"""Test cases for testing the names module."""
|
||||||
|
def test_on_domain_added(self):
|
||||||
|
"""Test adding a domain to the global list."""
|
||||||
|
on_domain_added('', '')
|
||||||
|
self.assertNotIn('', domain_types)
|
||||||
|
self.assertNotIn('', domains)
|
||||||
|
|
||||||
|
on_domain_added('', 'hiddenservice', 'ddddd.onion')
|
||||||
|
on_domain_added('', 'hiddenservice', 'eeeee.onion')
|
||||||
|
self.assertIn('ddddd.onion', domains['hiddenservice'])
|
||||||
|
self.assertIn('eeeee.onion', domains['hiddenservice'])
|
||||||
|
|
||||||
|
def test_on_domain_removed(self):
|
||||||
|
"""Test removing a domain from the global list."""
|
||||||
|
on_domain_added('', 'domainname', 'fffff')
|
||||||
|
on_domain_removed('', 'domainname', 'fffff')
|
||||||
|
self.assertNotIn('fffff', domains['domainname'])
|
||||||
|
|
||||||
|
on_domain_added('', 'pagekite', 'ggggg.pagekite.me')
|
||||||
|
on_domain_added('', 'pagekite', 'hhhhh.pagekite.me')
|
||||||
|
on_domain_removed('', 'pagekite')
|
||||||
|
self.assertNotIn('ggggg.pagekite.me', domains['pagekite'])
|
||||||
|
self.assertNotIn('hhhhh.pagekite.me', domains['pagekite'])
|
||||||
|
|
||||||
|
# try to remove things that don't exist
|
||||||
|
on_domain_removed('', '')
|
||||||
|
on_domain_removed('', 'domainname', 'iiiii')
|
||||||
|
|
||||||
|
def test_get_domain_types(self):
|
||||||
|
"""Test getting domain types."""
|
||||||
|
on_domain_added('', 'domainname')
|
||||||
|
self.assertIn('domainname', get_domain_types())
|
||||||
|
|
||||||
|
def test_get_description(self):
|
||||||
|
"""Test getting domain type description."""
|
||||||
|
on_domain_added('', 'pagekite', '', 'Pagekite')
|
||||||
|
self.assertEqual(get_description('pagekite'), 'Pagekite')
|
||||||
|
|
||||||
|
self.assertEqual('asdfasdf', get_description('asdfasdf'))
|
||||||
|
|
||||||
|
def test_get_domain(self):
|
||||||
|
"""Test getting a domain of domain_type."""
|
||||||
|
on_domain_added('', 'hiddenservice', 'aaaaa.onion')
|
||||||
|
self.assertEqual(get_domain('hiddenservice'), 'aaaaa.onion')
|
||||||
|
|
||||||
|
self.assertEqual('Not Available', get_domain('abcdef'))
|
||||||
|
|
||||||
|
on_domain_removed('', 'hiddenservice')
|
||||||
|
self.assertEqual('Not Available', get_domain('hiddenservice'))
|
||||||
|
|
||||||
|
def test_get_services(self):
|
||||||
|
"""Test getting enabled services for a domain."""
|
||||||
|
on_domain_added('', 'domainname', 'bbbbb', '',
|
||||||
|
['http', 'https', 'ssh'])
|
||||||
|
self.assertEqual(get_services('domainname', 'bbbbb'),
|
||||||
|
['http', 'https', 'ssh'])
|
||||||
|
|
||||||
|
self.assertEqual(get_services('xxxxx', 'yyyyy'), [])
|
||||||
|
self.assertEqual(get_services('domainname', 'zzzzz'), [])
|
||||||
|
|
||||||
|
def test_get_services_status(self):
|
||||||
|
"""Test getting whether each service is enabled for a domain."""
|
||||||
|
on_domain_added('', 'pagekite', 'ccccc.pagekite.me', '',
|
||||||
|
['http', 'https'])
|
||||||
|
self.assertEqual(get_services_status('pagekite', 'ccccc.pagekite.me'),
|
||||||
|
[True, True, False])
|
||||||
28
plinth/modules/names/urls.py
Normal file
28
plinth/modules/names/urls.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#
|
||||||
|
# This file is part of Plinth.
|
||||||
|
#
|
||||||
|
# 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/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
URLs for the name services module
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.conf.urls import patterns, url
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = patterns(
|
||||||
|
'plinth.modules.names.views',
|
||||||
|
url(r'^sys/names/$', 'index', name='index'),
|
||||||
|
)
|
||||||
52
plinth/modules/names/views.py
Normal file
52
plinth/modules/names/views.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#
|
||||||
|
# This file is part of Plinth.
|
||||||
|
#
|
||||||
|
# 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/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
Plinth module for name services
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.template.response import TemplateResponse
|
||||||
|
from gettext import gettext as _
|
||||||
|
|
||||||
|
from . import SERVICES, get_domain_types, get_description
|
||||||
|
from . import get_domain, get_services_status
|
||||||
|
|
||||||
|
|
||||||
|
def index(request):
|
||||||
|
"""Serve name services page."""
|
||||||
|
status = get_status()
|
||||||
|
|
||||||
|
return TemplateResponse(request, 'names.html',
|
||||||
|
{'title': _('Name Services'),
|
||||||
|
'status': status})
|
||||||
|
|
||||||
|
|
||||||
|
def get_status():
|
||||||
|
"""Get configured services per name."""
|
||||||
|
name_services = []
|
||||||
|
for domain_type in sorted(get_domain_types()):
|
||||||
|
domain = get_domain(domain_type)
|
||||||
|
name_services.append({
|
||||||
|
'type': get_description(domain_type),
|
||||||
|
'name': domain,
|
||||||
|
'services_enabled': get_services_status(domain_type, domain),
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
'services': [service[1] for service in SERVICES],
|
||||||
|
'name_services': name_services,
|
||||||
|
}
|
||||||
@ -21,10 +21,13 @@ Plinth module to configure PageKite
|
|||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from plinth import cfg
|
from plinth import cfg
|
||||||
|
from plinth.signals import domain_added
|
||||||
|
|
||||||
|
from . import utils
|
||||||
|
|
||||||
__all__ = ['init']
|
__all__ = ['init']
|
||||||
|
|
||||||
depends = ['plinth.modules.apps']
|
depends = ['plinth.modules.apps', 'plinth.modules.names']
|
||||||
|
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
@ -32,3 +35,26 @@ def init():
|
|||||||
menu = cfg.main_menu.get('apps:index')
|
menu = cfg.main_menu.get('apps:index')
|
||||||
menu.add_urlname(_('Public Visibility (PageKite)'),
|
menu.add_urlname(_('Public Visibility (PageKite)'),
|
||||||
'glyphicon-flag', 'pagekite:index', 800)
|
'glyphicon-flag', 'pagekite:index', 800)
|
||||||
|
|
||||||
|
# Register kite name with Name Services module.
|
||||||
|
try:
|
||||||
|
kite_name = utils.get_kite_details()['kite_name']
|
||||||
|
enabled = utils.get_pagekite_config()['enabled']
|
||||||
|
except IndexError:
|
||||||
|
# no data from 'pagekite get-kite'
|
||||||
|
kite_name = None
|
||||||
|
enabled_services = None
|
||||||
|
else:
|
||||||
|
if enabled and kite_name:
|
||||||
|
services = utils.get_pagekite_services()[0]
|
||||||
|
enabled_services = []
|
||||||
|
for service in services:
|
||||||
|
if services[service]:
|
||||||
|
enabled_services.append(service)
|
||||||
|
else:
|
||||||
|
kite_name = None
|
||||||
|
enabled_services = None
|
||||||
|
|
||||||
|
domain_added.send_robust(sender='pagekite', domain_type='pagekite',
|
||||||
|
name=kite_name, description=_('Pagekite'),
|
||||||
|
services=enabled_services)
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from plinth.errors import ActionError
|
from plinth.errors import ActionError
|
||||||
|
from plinth.signals import domain_added, domain_removed
|
||||||
from . import utils
|
from . import utils
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
@ -103,6 +104,20 @@ class ConfigurationForm(forms.Form):
|
|||||||
elif config_changed and new['enabled']:
|
elif config_changed and new['enabled']:
|
||||||
utils.run(['restart'])
|
utils.run(['restart'])
|
||||||
|
|
||||||
|
# Update kite name registered with Name Services module.
|
||||||
|
domain_removed.send_robust(
|
||||||
|
sender='pagekite', domain_type='pagekite')
|
||||||
|
if new['enabled'] and new['kite_name']:
|
||||||
|
services = utils.get_pagekite_services()[0]
|
||||||
|
enabled_services = []
|
||||||
|
for service in services:
|
||||||
|
if services[service]:
|
||||||
|
enabled_services.append(service)
|
||||||
|
domain_added.send_robust(
|
||||||
|
sender='pagekite', domain_type='pagekite',
|
||||||
|
name=new['kite_name'], description=_('Pagekite'),
|
||||||
|
services=enabled_services)
|
||||||
|
|
||||||
|
|
||||||
class StandardServiceForm(forms.Form):
|
class StandardServiceForm(forms.Form):
|
||||||
"""Creates a form out of PREDEFINED_SERVICES"""
|
"""Creates a form out of PREDEFINED_SERVICES"""
|
||||||
@ -135,6 +150,27 @@ class StandardServiceForm(forms.Form):
|
|||||||
messages.success(request, _('Service disabled: {name}')
|
messages.success(request, _('Service disabled: {name}')
|
||||||
.format(name=service_name))
|
.format(name=service_name))
|
||||||
|
|
||||||
|
# Update kite name services registered with Name Services module.
|
||||||
|
domain_removed.send_robust(
|
||||||
|
sender='pagekite', domain_type='pagekite')
|
||||||
|
try:
|
||||||
|
kite_name = utils.get_kite_details()['kite_name']
|
||||||
|
enabled = utils.get_pagekite_config()['enabled']
|
||||||
|
except IndexError:
|
||||||
|
# no data from 'pagekite get-kite'
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if enabled and kite_name:
|
||||||
|
services = utils.get_pagekite_services()[0]
|
||||||
|
enabled_services = []
|
||||||
|
for service in services:
|
||||||
|
if services[service]:
|
||||||
|
enabled_services.append(service)
|
||||||
|
domain_added.send_robust(
|
||||||
|
sender='pagekite', domain_type='pagekite',
|
||||||
|
name=kite_name, description=_('Pagekite'),
|
||||||
|
services=enabled_services)
|
||||||
|
|
||||||
|
|
||||||
class BaseCustomServiceForm(forms.Form):
|
class BaseCustomServiceForm(forms.Form):
|
||||||
"""Basic form functionality to handle a custom service"""
|
"""Basic form functionality to handle a custom service"""
|
||||||
|
|||||||
@ -28,7 +28,7 @@ from plinth import action_utils
|
|||||||
|
|
||||||
__all__ = ['tor', 'init']
|
__all__ = ['tor', 'init']
|
||||||
|
|
||||||
depends = ['plinth.modules.apps']
|
depends = ['plinth.modules.apps', 'plinth.modules.names']
|
||||||
|
|
||||||
|
|
||||||
def diagnose():
|
def diagnose():
|
||||||
|
|||||||
@ -32,6 +32,8 @@ from plinth import action_utils
|
|||||||
from plinth import cfg
|
from plinth import cfg
|
||||||
from plinth import package
|
from plinth import package
|
||||||
from plinth.errors import ActionError
|
from plinth.errors import ActionError
|
||||||
|
from plinth.modules.names import SERVICES
|
||||||
|
from plinth.signals import domain_added, domain_removed
|
||||||
|
|
||||||
APT_SOURCES_URI_PATHS = ('/files/etc/apt/sources.list/*/uri',
|
APT_SOURCES_URI_PATHS = ('/files/etc/apt/sources.list/*/uri',
|
||||||
'/files/etc/apt/sources.list.d/*/*/uri')
|
'/files/etc/apt/sources.list.d/*/*/uri')
|
||||||
@ -64,6 +66,25 @@ def init():
|
|||||||
menu.add_urlname(_('Anonymity Network (Tor)'), 'glyphicon-eye-close',
|
menu.add_urlname(_('Anonymity Network (Tor)'), 'glyphicon-eye-close',
|
||||||
'tor:index', 100)
|
'tor:index', 100)
|
||||||
|
|
||||||
|
# Register hidden service name with Name Services module.
|
||||||
|
enabled = action_utils.service_is_enabled('tor')
|
||||||
|
is_running = action_utils.service_is_running('tor')
|
||||||
|
(hs_enabled, hs_hostname, hs_ports) = get_hs()
|
||||||
|
|
||||||
|
if enabled and is_running and hs_enabled and hs_hostname:
|
||||||
|
hs_services = []
|
||||||
|
for service in SERVICES:
|
||||||
|
if str(service[2]) in hs_ports:
|
||||||
|
hs_services.append(service[0])
|
||||||
|
else:
|
||||||
|
hs_hostname = None
|
||||||
|
hs_services = None
|
||||||
|
|
||||||
|
domain_added.send_robust(
|
||||||
|
sender='tor', domain_type='hiddenservice',
|
||||||
|
name=hs_hostname, description=_('Tor Hidden Service'),
|
||||||
|
services=hs_services)
|
||||||
|
|
||||||
|
|
||||||
def on_install():
|
def on_install():
|
||||||
"""Setup Tor configuration as soon as it is installed."""
|
"""Setup Tor configuration as soon as it is installed."""
|
||||||
@ -167,18 +188,7 @@ def is_apt_transport_tor_enabled():
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def get_status():
|
def get_hs():
|
||||||
"""Return the current status"""
|
|
||||||
output = actions.superuser_run('tor', ['get-ports'])
|
|
||||||
port_info = output.split('\n')
|
|
||||||
ports = {}
|
|
||||||
for line in port_info:
|
|
||||||
try:
|
|
||||||
(key, val) = line.split()
|
|
||||||
ports[key] = val
|
|
||||||
except ValueError:
|
|
||||||
continue
|
|
||||||
|
|
||||||
output = actions.superuser_run('tor', ['get-hs'])
|
output = actions.superuser_run('tor', ['get-hs'])
|
||||||
output = output.strip()
|
output = output.strip()
|
||||||
if output == '':
|
if output == '':
|
||||||
@ -195,6 +205,23 @@ def get_status():
|
|||||||
hs_hostname = hs_info[0]
|
hs_hostname = hs_info[0]
|
||||||
hs_ports = hs_info[1]
|
hs_ports = hs_info[1]
|
||||||
|
|
||||||
|
return (hs_enabled, hs_hostname, hs_ports)
|
||||||
|
|
||||||
|
|
||||||
|
def get_status():
|
||||||
|
"""Return the current status"""
|
||||||
|
output = actions.superuser_run('tor', ['get-ports'])
|
||||||
|
port_info = output.split('\n')
|
||||||
|
ports = {}
|
||||||
|
for line in port_info:
|
||||||
|
try:
|
||||||
|
(key, val) = line.split()
|
||||||
|
ports[key] = val
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
(hs_enabled, hs_hostname, hs_ports) = get_hs()
|
||||||
|
|
||||||
return {'enabled': action_utils.service_is_enabled('tor'),
|
return {'enabled': action_utils.service_is_enabled('tor'),
|
||||||
'is_running': action_utils.service_is_running('tor'),
|
'is_running': action_utils.service_is_running('tor'),
|
||||||
'ports': ports,
|
'ports': ports,
|
||||||
@ -238,6 +265,25 @@ def __apply_changes(request, old_status, new_status):
|
|||||||
actions.superuser_run('tor', ['disable-hs'])
|
actions.superuser_run('tor', ['disable-hs'])
|
||||||
messages.success(request, _('Tor hidden service disabled'))
|
messages.success(request, _('Tor hidden service disabled'))
|
||||||
|
|
||||||
|
# Update hidden service name registered with Name Services module.
|
||||||
|
domain_removed.send_robust(
|
||||||
|
sender='tor', domain_type='hiddenservice')
|
||||||
|
|
||||||
|
enabled = action_utils.service_is_enabled('tor')
|
||||||
|
is_running = action_utils.service_is_running('tor')
|
||||||
|
(hs_enabled, hs_hostname, hs_ports) = get_hs()
|
||||||
|
|
||||||
|
if enabled and is_running and hs_enabled and hs_hostname:
|
||||||
|
hs_services = []
|
||||||
|
for service in SERVICES:
|
||||||
|
if str(service[2]) in hs_ports:
|
||||||
|
hs_services.append(service[0])
|
||||||
|
|
||||||
|
domain_added.send_robust(
|
||||||
|
sender='tor', domain_type='hiddenservice',
|
||||||
|
name=hs_hostname, description=_('Tor Hidden Service'),
|
||||||
|
services=hs_services)
|
||||||
|
|
||||||
if old_status['apt_transport_tor_enabled'] != \
|
if old_status['apt_transport_tor_enabled'] != \
|
||||||
new_status['apt_transport_tor_enabled']:
|
new_status['apt_transport_tor_enabled']:
|
||||||
if new_status['apt_transport_tor_enabled']:
|
if new_status['apt_transport_tor_enabled']:
|
||||||
|
|||||||
@ -28,3 +28,6 @@ post_module_loading = Signal()
|
|||||||
pre_hostname_change = Signal(providing_args=['old_hostname', 'new_hostname'])
|
pre_hostname_change = Signal(providing_args=['old_hostname', 'new_hostname'])
|
||||||
post_hostname_change = Signal(providing_args=['old_hostname', 'new_hostname'])
|
post_hostname_change = Signal(providing_args=['old_hostname', 'new_hostname'])
|
||||||
domainname_change = Signal(providing_args=['old_domainname', 'new_domainname'])
|
domainname_change = Signal(providing_args=['old_domainname', 'new_domainname'])
|
||||||
|
domain_added = Signal(providing_args=['domain_type', 'name', 'description',
|
||||||
|
'services'])
|
||||||
|
domain_removed = Signal(providing_args=['domain_type', 'name'])
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user