names: Use new API in all apps

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-08-01 16:18:08 -07:00 committed by James Valleroy
parent b684b07d11
commit ba4afd2a09
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
14 changed files with 108 additions and 224 deletions

View File

@ -156,9 +156,9 @@ def init():
# Register domain with Name Services module.
domainname = get_domainname()
if domainname:
domain_added.send_robust(
sender='config', domain_type='domainname', name=domainname,
description=ugettext_lazy('Domain Name'), services='__all__')
domain_added.send_robust(sender='config',
domain_type='domain-type-static',
name=domainname, services='__all__')
def setup(helper, old_version=None):

View File

@ -82,7 +82,7 @@ def _apply_changes(request, old_status, new_status):
if old_status['domainname'] != new_status['domainname']:
try:
set_domainname(new_status['domainname'])
set_domainname(new_status['domainname'], old_status['domainname'])
except Exception as exception:
messages.error(
request,
@ -141,7 +141,7 @@ def set_hostname(hostname):
actions.superuser_run('domainname-change', [domainname])
def set_domainname(domainname):
def set_domainname(domainname, old_domainname):
"""Sets machine domain name to domainname"""
old_domainname = config.get_domainname()
@ -156,8 +156,12 @@ def set_domainname(domainname):
new_domainname=domainname)
# Update domain registered with Name Services module.
domain_removed.send_robust(sender='config', domain_type='domainname')
if old_domainname:
domain_removed.send_robust(sender='config',
domain_type='domain-type-static',
name=old_domainname)
if domainname:
domain_added.send_robust(sender='config', domain_type='domainname',
name=domainname, description=_('Domain Name'),
services='__all__')
domain_added.send_robust(sender='config',
domain_type='domain-type-static',
name=domainname, services='__all__')

View File

@ -87,9 +87,8 @@ def init():
current_status = get_status()
if current_status['enabled']:
domain_added.send_robust(
sender='dynamicdns', domain_type='dynamicdnsservice',
name=current_status['dynamicdns_domain'],
description=_('Dynamic DNS Service'), services='__all__')
sender='dynamicdns', domain_type='domain-type-dynamic',
name=current_status['dynamicdns_domain'], services='__all__')
app.set_enabled(True)

View File

@ -156,15 +156,14 @@ def _apply_changes(request, old_status, new_status):
if old_status['enabled']:
domain_removed.send_robust(sender='dynamicdns',
domain_type='dynamicdnsservice',
domain_type='domain-type-dynamic',
name=old_status['dynamicdns_domain'])
_run(['stop'])
if new_status['enabled']:
domain_added.send_robust(
sender='dynamicdns', domain_type='dynamicdnsservice',
name=new_status['dynamicdns_domain'],
description=_('Dynamic DNS Service'), services='__all__')
sender='dynamicdns', domain_type='domain-type-dynamic',
name=new_status['dynamicdns_domain'], services='__all__')
_run(['start'])
messages.success(request, _('Configuration updated'))

View File

@ -160,7 +160,7 @@ def on_domainname_change(sender, old_domainname, new_domainname, **kwargs):
def on_domain_added(sender, domain_type='', name='', description='',
services=None, **kwargs):
"""Obtain a certificate for the new domain"""
if domain_type == 'hiddenservice':
if domain_type == 'domain-type-tor':
return False
# Check if a cert if already available

View File

@ -26,7 +26,7 @@ pytestmark = pytest.mark.usefixtures('needs_root', 'needs_sudo')
def test_add_onion_domain():
assert not on_domain_added('test', 'hiddenservice', 'ddddd.onion')
assert not on_domain_added('test', 'domain-type-tor', 'ddddd.onion')
@pytest.mark.usefixtures('load_cfg')

View File

@ -27,23 +27,15 @@ from plinth import cfg, menu
from plinth.signals import domain_added, domain_removed
from plinth.utils import format_lazy
from . import components
from .manifest import backup # noqa, pylint: disable=unused-import
SERVICES = (
('http', _('HTTP'), 80),
('https', _('HTTPS'), 443),
('ssh', _('SSH'), 22),
)
version = 1
is_essential = True
name = _('Name Services')
domain_types = {}
domains = {}
logger = logging.getLogger(__name__)
manual_page = 'NameServices'
@ -89,70 +81,27 @@ def on_domain_added(sender, domain_type, name='', description='',
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
components.DomainName('domain-' + sender + '-' + name, name, domain_type,
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]
if name:
component_id = 'domain-' + sender + '-' + name
components.DomainName.get(component_id).remove()
logger.info('Removed domain %s of type %s', name, domain_type)
else:
for domain_name in components.DomainName.list():
if domain_name.domain_type.component_id == domain_type:
domain_name.remove()
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]
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 domains[domain_type]:
return list(domains[domain_type].keys())[0]
return None
def get_enabled_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_enabled_services(domain_type, domain)
return [
enabled == '__all__' or service[0] in enabled for service in SERVICES
]
logger.info('Remove domain %s of type %s', domain_name.name,
domain_type)

View File

@ -26,30 +26,38 @@
<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 %}
<th>Type</th>
<th>Domain Name</th>
<th>Services</th>
<th></th>
</tr>
</thead>
<tbody>
{% for name_service in status.name_services %}
{% for domain in status.domains|dictsort:"domain_type.display_name" %}
<tr>
<td>{{ domain.domain_type.display_name }}</td>
<td>{{ domain.name }}</td>
<td>{{ domain.get_readable_services|join:', ' }}</td>
<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">{% trans "Enabled" %}</span>
{% else %}
<span class="label label-warning">{% trans "Disabled" %}</span>
{% endif %}
<a href="{% url domain.domain_type.configuration_url %}"
role="button" class="btn btn-md btn-default">
{% trans "Configure" %}
</a>
</td>
</tr>
{% endfor %}
{% for domain_type in status.unused_domain_types %}
<tr>
<td>{{ domain_type.display_name }}</td>
<td>-</td>
<td>-</td>
<td>
<a href="{% url domain_type.configuration_url %}"
role="button" class="btn btn-md btn-default">
{% trans "Configure" %}
</a>
</td>
</tr>
{% endfor %}
</tbody>

View File

@ -20,99 +20,39 @@ Tests for names module.
import pytest
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_enabled_services, get_services_status
from ..components import DomainName, DomainType
@pytest.fixture(name='clean_domains')
def fixture_clean_domains():
"""Test fixture to start a test with clean domains list."""
old_domain_types = dict(domain_types)
old_domains = dict(domains)
domain_types.clear()
domains.clear()
yield
domain_types.clear()
domains.clear()
domain_types.update(old_domain_types)
domains.update(old_domains)
DomainName._all = {} # pylint: disable=protected-access
@pytest.mark.usefixtures('clean_domains')
def test_on_domain_added():
"""Test adding a domain to the global list."""
on_domain_added('', '')
assert '' not in domain_types
assert '' not in domains
assert not DomainName.list()
on_domain_added('', 'hiddenservice', 'ddddd.onion')
on_domain_added('', 'hiddenservice', 'eeeee.onion')
assert 'ddddd.onion' in domains['hiddenservice']
assert 'eeeee.onion' in domains['hiddenservice']
DomainType('domain-type-tor', 'Tor Domain', 'torurl')
on_domain_added('tor', 'domain-type-tor', 'ddddd.onion')
on_domain_added('tor', 'domain-type-tor', 'eeeee.onion')
DomainName.get('domain-tor-ddddd.onion')
DomainName.get('domain-tor-eeeee.onion')
@pytest.mark.usefixtures('clean_domains')
def test_on_domain_removed():
"""Test removing a domain from the global list."""
on_domain_added('', 'domainname', 'fffff')
on_domain_removed('', 'domainname', 'fffff')
assert 'fffff' not in domains['domainname']
on_domain_added('', 'pagekite', 'ggggg.pagekite.me')
on_domain_added('', 'pagekite', 'hhhhh.pagekite.me')
on_domain_removed('', 'pagekite')
assert 'ggggg.pagekite.me' not in domains['pagekite']
assert 'hhhhh.pagekite.me' not in domains['pagekite']
DomainType('domain-type-tor', 'Tor Domain', 'torurl')
on_domain_added('tor', 'domain-type-tor', 'ddddd.onion')
on_domain_removed('tor', 'domain-type-tor', 'ddddd.onion')
with pytest.raises(KeyError):
DomainName.get('domain-tor-ddddd.onion')
# try to remove things that don't exist
on_domain_removed('', '')
with pytest.raises(KeyError):
on_domain_removed('', 'domainname', 'iiiii')
@pytest.mark.usefixtures('clean_domains')
def test_get_domain_types():
"""Test getting domain types."""
on_domain_added('', 'domainname')
assert 'domainname' in get_domain_types()
@pytest.mark.usefixtures('clean_domains')
def test_get_description():
"""Test getting domain type description."""
on_domain_added('', 'pagekite', '', 'Pagekite')
assert get_description('pagekite') == 'Pagekite'
assert get_description('asdfasdf') == 'asdfasdf'
@pytest.mark.usefixtures('clean_domains')
def test_get_domain():
"""Test getting a domain of domain_type."""
on_domain_added('', 'hiddenservice', 'aaaaa.onion')
assert get_domain('hiddenservice') == 'aaaaa.onion'
assert get_domain('abcdef') is None
on_domain_removed('', 'hiddenservice')
assert get_domain('hiddenservice') is None
@pytest.mark.usefixtures('clean_domains')
def test_get_enabled_services():
"""Test getting enabled services for a domain."""
on_domain_added('', 'domainname', 'bbbbb', '', ['http', 'https', 'ssh'])
assert get_enabled_services('domainname',
'bbbbb') == ['http', 'https', 'ssh']
assert get_enabled_services('xxxxx', 'yyyyy') == []
assert get_enabled_services('domainname', 'zzzzz') == []
@pytest.mark.usefixtures('clean_domains')
def test_get_services_status():
"""Test getting whether each service is enabled for a domain."""
on_domain_added('', 'pagekite', 'ccccc.pagekite.me', '', ['http', 'https'])
assert get_services_status('pagekite', 'ccccc.pagekite.me') == \
[True, True, False]

View File

@ -19,12 +19,10 @@ FreedomBox app for name services.
"""
from django.template.response import TemplateResponse
from django.utils.translation import ugettext as _
from plinth.modules import names
from . import (SERVICES, get_description, get_domain, get_domain_types,
get_services_status)
from . import components
def index(request):
@ -42,16 +40,11 @@ def index(request):
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 or _('Not Available'),
'services_enabled': get_services_status(domain_type, domain),
})
domains = components.DomainName.list()
used_domain_types = {domain.domain_type for domain in domains}
unused_domain_types = [
domain_type for domain_type in components.DomainType.list().values()
if domain_type not in used_domain_types
]
return {
'services': [service[1] for service in SERVICES],
'name_services': name_services,
}
return {'domains': domains, 'unused_domain_types': unused_domain_types}

View File

@ -260,7 +260,8 @@ def update_names_module(initial_registration=False, enabled=None,
- enabled: Boolean (optional) whether PageKite is enabled
- kite_name: String (optional)
"""
domain_removed.send_robust(sender='pagekite', domain_type='pagekite')
domain_removed.send_robust(sender='pagekite',
domain_type='domain-type-pagekite')
if enabled is None:
try:
@ -284,9 +285,9 @@ def update_names_module(initial_registration=False, enabled=None,
kite_name = None
if initial_registration or (enabled and kite_name):
domain_added.send_robust(sender='pagekite', domain_type='pagekite',
name=kite_name, description=_('Pagekite'),
services=enabled_services)
domain_added.send_robust(sender='pagekite',
domain_type='domain-type-pagekite',
name=kite_name, services=enabled_services)
if __name__ == "__main__":

View File

@ -27,7 +27,6 @@ from plinth import app as app_module
from plinth import menu
from plinth.daemon import Daemon
from plinth.modules.firewall.components import Firewall
from plinth.modules.names import SERVICES
from plinth.modules.names.components import DomainType
from plinth.signals import domain_added, domain_removed
@ -110,21 +109,13 @@ def init():
# Register hidden service name with Name Services module.
status = utils.get_status()
hostname = status['hs_hostname']
hs_virtports = [port['virtport'] for port in status['hs_ports']]
services = [int(port['virtport']) for port in status['hs_ports']]
if status['enabled'] and status['is_running'] and \
status['hs_enabled'] and status['hs_hostname']:
hs_services = []
for service_type in SERVICES:
if str(service_type[2]) in hs_virtports:
hs_services.append(service_type[0])
else:
hostname = None
hs_services = None
domain_added.send_robust(
sender='tor', domain_type='hiddenservice', name=hostname,
description=_('Tor Hidden Service'), services=hs_services)
domain_added.send_robust(sender='tor',
domain_type='domain-type-tor',
name=hostname, services=services)
def setup(helper, old_version=None):
@ -146,14 +137,13 @@ def update_hidden_service_domain(status=None):
if not status:
status = utils.get_status()
domain_removed.send_robust(sender='tor', domain_type='hiddenservice')
domain_removed.send_robust(sender='tor', domain_type='domain-type-tor')
if status['enabled'] and status['is_running'] and \
status['hs_enabled'] and status['hs_hostname']:
domain_added.send_robust(sender='tor', domain_type='hiddenservice',
name=status['hs_hostname'],
description=_('Tor Hidden Service'),
services=status['hs_services'])
services = [int(port['virtport']) for port in status['hs_ports']]
domain_added.send_robust(sender='tor', domain_type='domain-type-tor',
name=status['hs_hostname'], services=services)
def diagnose():

View File

@ -74,9 +74,7 @@
<td class="tor-hs-hostname">{{ status.hs_hostname }}</td>
<td class="tor-hs-status">{{ status.hs_status }}</td>
<td class="tor-hs-services">
{% for service in status.hs_services %}
{{ service }}
{% endfor %}
{{ status.hs_services|join:', ' }}
</td>
</tr>
</tbody>

View File

@ -27,7 +27,7 @@ import augeas
from plinth import actions
from plinth.daemon import app_is_running
from plinth.modules import tor
from plinth.modules.names import SERVICES
from plinth.modules.names.components import DomainName
APT_SOURCES_URI_PATHS = ('/files/etc/apt/sources.list/*/uri',
'/files/etc/apt/sources.list.d/*/*/uri')
@ -41,10 +41,13 @@ def get_status():
hs_info = status['hidden_service']
hs_services = []
hs_virtports = [port['virtport'] for port in hs_info['ports']]
for service_type in SERVICES:
if str(service_type[2]) in hs_virtports:
hs_services.append(service_type[0])
if hs_info['hostname']:
try:
domain = DomainName.get('domain-tor-' + hs_info['hostname'])
except KeyError:
pass
else:
hs_services = domain.get_readable_services()
# Filter out obfs3/4 ports when bridge relay is disabled
ports = {