mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-04-29 10:10:19 +00:00
monkeysphere: New module for verifying SSH servers
monkeysphere: Run publish as background task, allow user to cancel. Small fixes to names module: - Remove unused ugettext import. - Change SERVICES to tuple. - If a domain is not available for a service type, return None instead of (translated) "Not Available". - Rename get_services -> get_enabled_services.
This commit is contained in:
parent
447f067734
commit
70d85cbd6f
126
actions/monkeysphere
Executable file
126
actions/monkeysphere
Executable file
@ -0,0 +1,126 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
#
|
||||||
|
# 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/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
Configuration helper for monkeysphere.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
HOST_TOOL = 'monkeysphere-host'
|
||||||
|
|
||||||
|
|
||||||
|
def parse_arguments():
|
||||||
|
"""Return parsed command line arguments as dictionary."""
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')
|
||||||
|
|
||||||
|
host_show_key = subparsers.add_parser('host-show-key',
|
||||||
|
help='Show host key fingerprint')
|
||||||
|
host_show_key.add_argument('keyid', nargs='*',
|
||||||
|
help='Optional list of KEYIDs')
|
||||||
|
|
||||||
|
host_import_ssh_key = subparsers.add_parser('host-import-ssh-key',
|
||||||
|
help='Import host SSH key')
|
||||||
|
host_import_ssh_key.add_argument('hostname',
|
||||||
|
help='Fully-qualified hostname')
|
||||||
|
|
||||||
|
host_publish_key = subparsers.add_parser(
|
||||||
|
'host-publish-key',
|
||||||
|
help='Push host key to keyserver')
|
||||||
|
host_publish_key.add_argument(
|
||||||
|
'keyid', nargs='*',
|
||||||
|
help='Optional list of KEYIDs')
|
||||||
|
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_host_show_key(arguments):
|
||||||
|
"""Show host key fingerprint."""
|
||||||
|
keyid = ' '.join(arguments.keyid)
|
||||||
|
try:
|
||||||
|
output = subprocess.check_output([HOST_TOOL, 'show-key', keyid])
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
# no keys available
|
||||||
|
return
|
||||||
|
|
||||||
|
# parse output
|
||||||
|
keys = [dict()]
|
||||||
|
lines = output.decode().strip().split('\n')
|
||||||
|
for line in lines:
|
||||||
|
if line.startswith('pub'):
|
||||||
|
data = line.lstrip('pub').split()
|
||||||
|
keys[-1]['pub'] = data[0]
|
||||||
|
keys[-1]['date'] = data[1]
|
||||||
|
elif line.startswith('uid'):
|
||||||
|
keys[-1]['uid'] = line.lstrip('uid').strip()
|
||||||
|
elif line.startswith('OpenPGP fingerprint:'):
|
||||||
|
keys[-1]['pgp_fingerprint'] = line.lstrip('Open PGP fingerprint:')
|
||||||
|
elif line.startswith('ssh fingerprint:'):
|
||||||
|
data = line.lstrip('ssh fingerprint:').split()
|
||||||
|
keys[-1]['ssh_keysize'] = data[0]
|
||||||
|
keys[-1]['ssh_fingerprint'] = data[1]
|
||||||
|
keys[-1]['ssh_keytype'] = data[2].strip('()')
|
||||||
|
elif line == '':
|
||||||
|
keys.append(dict())
|
||||||
|
|
||||||
|
for key in keys:
|
||||||
|
print(key['pub'], key['date'], key['uid'], key['pgp_fingerprint'],
|
||||||
|
key['ssh_keysize'], key['ssh_fingerprint'], key['ssh_keytype'])
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_host_import_ssh_key(arguments):
|
||||||
|
"""Import host SSH key."""
|
||||||
|
output = subprocess.check_output(
|
||||||
|
[HOST_TOOL, 'import-key',
|
||||||
|
'/etc/ssh/ssh_host_rsa_key', arguments.hostname])
|
||||||
|
print(output.decode())
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_host_publish_key(arguments):
|
||||||
|
"""Push host key to keyserver."""
|
||||||
|
keyid = ' '.join(arguments.keyid)
|
||||||
|
# setting TMPDIR as workaround for Debian bug #656750
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
[HOST_TOOL, 'publish-keys', keyid],
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False,
|
||||||
|
env=dict(
|
||||||
|
os.environ,
|
||||||
|
TMPDIR='/var/lib/monkeysphere/authentication/tmp/',
|
||||||
|
MONKEYSPHERE_PROMPT='false'))
|
||||||
|
output, error = proc.communicate()
|
||||||
|
output, error = output.decode(), error.decode()
|
||||||
|
if proc.returncode != 0:
|
||||||
|
raise Exception(output, error)
|
||||||
|
|
||||||
|
print(output)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Parse arguments and perform all duties."""
|
||||||
|
arguments = parse_arguments()
|
||||||
|
|
||||||
|
subcommand = arguments.subcommand.replace('-', '_')
|
||||||
|
subcommand_method = globals()['subcommand_' + subcommand]
|
||||||
|
subcommand_method(arguments)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
1
data/etc/plinth/modules-enabled/monkeysphere
Normal file
1
data/etc/plinth/modules-enabled/monkeysphere
Normal file
@ -0,0 +1 @@
|
|||||||
|
plinth.modules.monkeysphere
|
||||||
33
plinth/modules/monkeysphere/__init__.py
Normal file
33
plinth/modules/monkeysphere/__init__.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#
|
||||||
|
# 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 monkeysphere.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from plinth import cfg
|
||||||
|
|
||||||
|
depends = ['plinth.modules.system']
|
||||||
|
|
||||||
|
|
||||||
|
def init():
|
||||||
|
"""Initialize the monkeysphere module."""
|
||||||
|
menu = cfg.main_menu.get('system:index')
|
||||||
|
menu.add_urlname(_('Monkeysphere'), 'glyphicon-certificate',
|
||||||
|
'monkeysphere:index', 970)
|
||||||
108
plinth/modules/monkeysphere/templates/monkeysphere.html
Normal file
108
plinth/modules/monkeysphere/templates/monkeysphere.html
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
{% 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 %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block page_head %}
|
||||||
|
|
||||||
|
{% if running %}
|
||||||
|
<meta http-equiv="refresh" content="3"/>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<h2>{% trans "Monkeysphere" %}</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{% blocktrans trimmed with box_name=cfg.box_name %}
|
||||||
|
With Monkeysphere, a PGP key can be generated for each domain
|
||||||
|
serving SSH on this {{ box_name }}. The PGP public key can then be
|
||||||
|
uploaded to the PGP keyservers. Users connecting to this {{ box_name }}
|
||||||
|
through SSH can verify that they are connecting to the correct
|
||||||
|
host. See the
|
||||||
|
<a href="http://web.monkeysphere.info/getting-started-ssh/">
|
||||||
|
Monkeysphere SSH documentation</a> for more details.
|
||||||
|
{% endblocktrans %}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{% if running %}
|
||||||
|
<p class="running-status-parent">
|
||||||
|
<span class="running-status active"></span>
|
||||||
|
{% trans "Publishing key to keyserver..." %}
|
||||||
|
|
||||||
|
<form class="form" method="post"
|
||||||
|
action="{% url 'monkeysphere:cancel' %}">
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-warning btn-sm">
|
||||||
|
{% trans "Cancel" %}</button>
|
||||||
|
</form>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<table class="table table-bordered table-condensed table-striped">
|
||||||
|
{% for name_service in status.name_services %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<b>{{ name_service.type }}</b><br>
|
||||||
|
<i>{{ name_service.name }}</i>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if name_service.key %}
|
||||||
|
{{ name_service.key.pgp_fingerprint }}
|
||||||
|
{% else %}
|
||||||
|
{% trans "Not Available" %}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if name_service.available %}
|
||||||
|
{% if not name_service.key %}
|
||||||
|
<form class="form" method="post"
|
||||||
|
action="{% url 'monkeysphere:generate' name_service.short_type %}">
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary btn-sm pull-right">
|
||||||
|
{% trans "Generate PGP Key" %}</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% elif not running %}
|
||||||
|
<form class="form" method="post"
|
||||||
|
action="{% url 'monkeysphere:publish' name_service.key.pgp_fingerprint %}">
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-warning btn-sm pull-right">
|
||||||
|
{% trans "Publish Key" %}</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
0
plinth/modules/monkeysphere/tests/__init__.py
Normal file
0
plinth/modules/monkeysphere/tests/__init__.py
Normal file
34
plinth/modules/monkeysphere/urls.py
Normal file
34
plinth/modules/monkeysphere/urls.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#
|
||||||
|
# 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 monkeysphere module.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^sys/monkeysphere/$', views.index, name='index'),
|
||||||
|
url(r'^sys/monkeysphere/(?P<service>[\w]+)/generate/$',
|
||||||
|
views.generate, name='generate'),
|
||||||
|
url(r'^sys/monkeysphere/(?P<fingerprint>[\w]+)/publish/$',
|
||||||
|
views.publish, name='publish'),
|
||||||
|
url(r'^sys/monkeysphere/cancel/$', views.cancel, name='cancel'),
|
||||||
|
]
|
||||||
144
plinth/modules/monkeysphere/views.py
Normal file
144
plinth/modules/monkeysphere/views.py
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
#
|
||||||
|
# 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/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
Views for the monkeysphere module.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.contrib import messages
|
||||||
|
from django.core.urlresolvers import reverse_lazy
|
||||||
|
from django.shortcuts import redirect
|
||||||
|
from django.template.response import TemplateResponse
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
from django.views.decorators.http import require_POST
|
||||||
|
|
||||||
|
from plinth import actions
|
||||||
|
from plinth import package
|
||||||
|
from plinth.modules import names
|
||||||
|
|
||||||
|
publish_process = None
|
||||||
|
|
||||||
|
|
||||||
|
@package.required(['monkeysphere'])
|
||||||
|
def index(request):
|
||||||
|
"""Serve configuration page."""
|
||||||
|
_collect_publish_result(request)
|
||||||
|
status = get_status()
|
||||||
|
return TemplateResponse(
|
||||||
|
request, 'monkeysphere.html',
|
||||||
|
{'title': _('Monkeysphere'),
|
||||||
|
'status': status,
|
||||||
|
'running': bool(publish_process)})
|
||||||
|
|
||||||
|
|
||||||
|
@require_POST
|
||||||
|
def generate(request, service):
|
||||||
|
"""Generate PGP key for SSH service."""
|
||||||
|
for domain_type in sorted(names.get_domain_types()):
|
||||||
|
if domain_type == service:
|
||||||
|
domain = names.get_domain(domain_type)
|
||||||
|
|
||||||
|
try:
|
||||||
|
actions.superuser_run(
|
||||||
|
'monkeysphere',
|
||||||
|
['host-import-ssh-key', 'ssh://' + domain])
|
||||||
|
messages.success(request, _('Generated PGP key'))
|
||||||
|
except actions.ActionError as exception:
|
||||||
|
messages.error(request, str(exception))
|
||||||
|
|
||||||
|
return redirect(reverse_lazy('monkeysphere:index'))
|
||||||
|
|
||||||
|
|
||||||
|
@require_POST
|
||||||
|
def publish(request, fingerprint):
|
||||||
|
"""Publish PGP key for SSH service."""
|
||||||
|
global publish_process
|
||||||
|
if not publish_process:
|
||||||
|
publish_process = actions.superuser_run(
|
||||||
|
'monkeysphere', ['host-publish-key', fingerprint], async=True)
|
||||||
|
|
||||||
|
return redirect(reverse_lazy('monkeysphere:index'))
|
||||||
|
|
||||||
|
|
||||||
|
@require_POST
|
||||||
|
def cancel(request):
|
||||||
|
"""Cancel ongoing process."""
|
||||||
|
global publish_process
|
||||||
|
if publish_process:
|
||||||
|
publish_process.terminate()
|
||||||
|
publish_process = None
|
||||||
|
messages.info(request, _('Cancelled publish key.'))
|
||||||
|
|
||||||
|
return redirect(reverse_lazy('monkeysphere:index'))
|
||||||
|
|
||||||
|
|
||||||
|
def get_status():
|
||||||
|
"""Get the current status."""
|
||||||
|
output = actions.superuser_run('monkeysphere', ['host-show-key'])
|
||||||
|
keys = []
|
||||||
|
for line in output.split('\n'):
|
||||||
|
data = line.strip().split()
|
||||||
|
if data and len(data) == 7:
|
||||||
|
keys.append(dict())
|
||||||
|
keys[-1]['pub'] = data[0]
|
||||||
|
keys[-1]['date'] = data[1]
|
||||||
|
keys[-1]['uid'] = data[2]
|
||||||
|
keys[-1]['name'] = data[2].replace('ssh://', '')
|
||||||
|
keys[-1]['pgp_fingerprint'] = data[3]
|
||||||
|
keys[-1]['ssh_keysize'] = data[4]
|
||||||
|
keys[-1]['ssh_fingerprint'] = data[5]
|
||||||
|
keys[-1]['ssh_keytype'] = data[6]
|
||||||
|
|
||||||
|
name_services = []
|
||||||
|
for domain_type in sorted(names.get_domain_types()):
|
||||||
|
domain = names.get_domain(domain_type)
|
||||||
|
name_services.append({
|
||||||
|
'type': names.get_description(domain_type),
|
||||||
|
'short_type': domain_type,
|
||||||
|
'name': domain or _('Not Available'),
|
||||||
|
'available': bool(domain),
|
||||||
|
'key': None,
|
||||||
|
})
|
||||||
|
|
||||||
|
# match up keys with name services
|
||||||
|
for key in keys:
|
||||||
|
for name_service in name_services:
|
||||||
|
if key['name'] == name_service['name']:
|
||||||
|
name_service['key'] = key
|
||||||
|
continue
|
||||||
|
|
||||||
|
return {'name_services': name_services}
|
||||||
|
|
||||||
|
|
||||||
|
def _collect_publish_result(request):
|
||||||
|
"""Handle publish process completion."""
|
||||||
|
global publish_process
|
||||||
|
if not publish_process:
|
||||||
|
return
|
||||||
|
|
||||||
|
return_code = publish_process.poll()
|
||||||
|
|
||||||
|
# Publish process is not complete yet
|
||||||
|
if return_code is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not return_code:
|
||||||
|
messages.success(request, _('Published key to keyserver.'))
|
||||||
|
else:
|
||||||
|
messages.error(request, _('Error occurred while publishing key.'))
|
||||||
|
|
||||||
|
publish_process = None
|
||||||
@ -19,18 +19,17 @@
|
|||||||
Plinth module to configure name services
|
Plinth module to configure name services
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
from django.utils.translation import ugettext_lazy as _
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from plinth import cfg
|
from plinth import cfg
|
||||||
from plinth.signals import domain_added, domain_removed
|
from plinth.signals import domain_added, domain_removed
|
||||||
|
|
||||||
|
SERVICES = (
|
||||||
SERVICES = [
|
('http', _('HTTP'), 80),
|
||||||
('http', ugettext_lazy('HTTP'), 80),
|
('https', _('HTTPS'), 443),
|
||||||
('https', ugettext_lazy('HTTPS'), 443),
|
('ssh', _('SSH'), 22),
|
||||||
('ssh', ugettext_lazy('SSH'), 22),
|
)
|
||||||
]
|
|
||||||
|
|
||||||
depends = ['plinth.modules.system']
|
depends = ['plinth.modules.system']
|
||||||
|
|
||||||
@ -43,7 +42,7 @@ logger = logging.getLogger(__name__)
|
|||||||
def init():
|
def init():
|
||||||
"""Initialize the names module."""
|
"""Initialize the names module."""
|
||||||
menu = cfg.main_menu.get('system:index')
|
menu = cfg.main_menu.get('system:index')
|
||||||
menu.add_urlname(ugettext_lazy('Name Services'), 'glyphicon-tag',
|
menu.add_urlname(_('Name Services'), 'glyphicon-tag',
|
||||||
'names:index', 19)
|
'names:index', 19)
|
||||||
|
|
||||||
domain_added.connect(on_domain_added)
|
domain_added.connect(on_domain_added)
|
||||||
@ -104,10 +103,10 @@ def get_domain(domain_type):
|
|||||||
if domain_type in domains and len(domains[domain_type]) > 0:
|
if domain_type in domains and len(domains[domain_type]) > 0:
|
||||||
return list(domains[domain_type].keys())[0]
|
return list(domains[domain_type].keys())[0]
|
||||||
else:
|
else:
|
||||||
return _('Not Available')
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_services(domain_type, domain):
|
def get_enabled_services(domain_type, domain):
|
||||||
"""Get list of enabled services for a domain."""
|
"""Get list of enabled services for a domain."""
|
||||||
try:
|
try:
|
||||||
return domains[domain_type][domain]
|
return domains[domain_type][domain]
|
||||||
@ -118,5 +117,5 @@ def get_services(domain_type, domain):
|
|||||||
|
|
||||||
def get_services_status(domain_type, domain):
|
def get_services_status(domain_type, domain):
|
||||||
"""Get list of whether each service is enabled for a domain."""
|
"""Get list of whether each service is enabled for a domain."""
|
||||||
enabled = get_services(domain_type, domain)
|
enabled = get_enabled_services(domain_type, domain)
|
||||||
return [service[0] in enabled for service in SERVICES]
|
return [service[0] in enabled for service in SERVICES]
|
||||||
|
|||||||
@ -24,7 +24,7 @@ import unittest
|
|||||||
from .. import domain_types, domains
|
from .. import domain_types, domains
|
||||||
from .. import on_domain_added, on_domain_removed
|
from .. import on_domain_added, on_domain_removed
|
||||||
from .. import get_domain_types, get_description
|
from .. import get_domain_types, get_description
|
||||||
from .. import get_domain, get_services, get_services_status
|
from .. import get_domain, get_enabled_services, get_services_status
|
||||||
|
|
||||||
|
|
||||||
class TestNames(unittest.TestCase):
|
class TestNames(unittest.TestCase):
|
||||||
@ -73,20 +73,20 @@ class TestNames(unittest.TestCase):
|
|||||||
on_domain_added('', 'hiddenservice', 'aaaaa.onion')
|
on_domain_added('', 'hiddenservice', 'aaaaa.onion')
|
||||||
self.assertEqual(get_domain('hiddenservice'), 'aaaaa.onion')
|
self.assertEqual(get_domain('hiddenservice'), 'aaaaa.onion')
|
||||||
|
|
||||||
self.assertEqual('Not Available', get_domain('abcdef'))
|
self.assertEqual(None, get_domain('abcdef'))
|
||||||
|
|
||||||
on_domain_removed('', 'hiddenservice')
|
on_domain_removed('', 'hiddenservice')
|
||||||
self.assertEqual('Not Available', get_domain('hiddenservice'))
|
self.assertEqual(None, get_domain('hiddenservice'))
|
||||||
|
|
||||||
def test_get_services(self):
|
def test_get_enabled_services(self):
|
||||||
"""Test getting enabled services for a domain."""
|
"""Test getting enabled services for a domain."""
|
||||||
on_domain_added('', 'domainname', 'bbbbb', '',
|
on_domain_added('', 'domainname', 'bbbbb', '',
|
||||||
['http', 'https', 'ssh'])
|
['http', 'https', 'ssh'])
|
||||||
self.assertEqual(get_services('domainname', 'bbbbb'),
|
self.assertEqual(get_enabled_services('domainname', 'bbbbb'),
|
||||||
['http', 'https', 'ssh'])
|
['http', 'https', 'ssh'])
|
||||||
|
|
||||||
self.assertEqual(get_services('xxxxx', 'yyyyy'), [])
|
self.assertEqual(get_enabled_services('xxxxx', 'yyyyy'), [])
|
||||||
self.assertEqual(get_services('domainname', 'zzzzz'), [])
|
self.assertEqual(get_enabled_services('domainname', 'zzzzz'), [])
|
||||||
|
|
||||||
def test_get_services_status(self):
|
def test_get_services_status(self):
|
||||||
"""Test getting whether each service is enabled for a domain."""
|
"""Test getting whether each service is enabled for a domain."""
|
||||||
|
|||||||
@ -42,7 +42,7 @@ def get_status():
|
|||||||
domain = get_domain(domain_type)
|
domain = get_domain(domain_type)
|
||||||
name_services.append({
|
name_services.append({
|
||||||
'type': get_description(domain_type),
|
'type': get_description(domain_type),
|
||||||
'name': domain,
|
'name': domain or _('Not Available'),
|
||||||
'services_enabled': get_services_status(domain_type, domain),
|
'services_enabled': get_services_status(domain_type, domain),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user