diff --git a/actions/i2p b/actions/i2p new file mode 100755 index 000000000..f56d553aa --- /dev/null +++ b/actions/i2p @@ -0,0 +1,93 @@ +#!/usr/bin/python3 +# +# 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 . +# + +""" +Wrapper to list and handle system services +""" + +import argparse +import os + +from plinth import action_utils, cfg + +cfg.read() +module_config_path = os.path.join(cfg.config_dir, 'modules-enabled') + + +def add_service_action(subparsers, action, help): + parser = subparsers.add_parser(action, help=help) + + +def parse_arguments(): + """Return parsed command line arguments as dictionary.""" + parser = argparse.ArgumentParser() + subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') + + add_service_action(subparsers, 'start', 'start i2p service') + add_service_action(subparsers, 'stop', 'stop i2p service') + add_service_action(subparsers, 'enable', 'enable i2p service') + add_service_action(subparsers, 'disable', 'disable i2p service') + add_service_action(subparsers, 'restart', 'restart i2p service') + add_service_action(subparsers, 'is-running', 'status of a service') + add_service_action(subparsers, 'is-enabled', 'status a service') + + subparsers.required = True + return parser.parse_args() + + +def subcommand_start(): + action_utils.service_start("i2p") + + +def subcommand_stop(): + action_utils.service_stop("i2p") + + +def subcommand_enable(): + action_utils.service_enable("i2p") + action_utils.webserver_enable("i2p-plinth") + + +def subcommand_disable(): + action_utils.service_disable("i2p") + action_utils.webserver_disable("i2p-plinth") + + +def subcommand_restart(): + action_utils.service_restart("i2p") + + +def subcommand_is_enabled(): + print(action_utils.service_is_enabled("i2p")) + + +def subcommand_is_running(): + print(action_utils.service_is_running("i2p")) + + +def main(): + """Parse arguments and perform all duties.""" + arguments = parse_arguments() + + subcommand = arguments.subcommand.replace('-', '_') + subcommand_method = globals()['subcommand_' + subcommand] + subcommand_method() + + +if __name__ == '__main__': + main() diff --git a/data/etc/apache2/conf-available/i2p-plinth.conf b/data/etc/apache2/conf-available/i2p-plinth.conf new file mode 100644 index 000000000..3aa37a579 --- /dev/null +++ b/data/etc/apache2/conf-available/i2p-plinth.conf @@ -0,0 +1,22 @@ +## +## On all sites, provide Transmission on a default path: /i2p +## +## Requires the following Apache modules to be enabled: +## mod_headers +## mod_proxy +## mod_proxy_http +## mod_proxy_html +## + + ProxyPass http://localhost:7657 + ProxyPassReverse http://localhost:7657 + + # Rewrite absolute urls from i2p to pass through apache + ProxyHTMLEnable On + ProxyHTMLURLMap / /i2p/ + + Include includes/freedombox-single-sign-on.conf + + TKTAuthToken "admin" "i2p" + + diff --git a/data/etc/plinth/modules-enabled/i2p b/data/etc/plinth/modules-enabled/i2p new file mode 100644 index 000000000..77c98ea19 --- /dev/null +++ b/data/etc/plinth/modules-enabled/i2p @@ -0,0 +1 @@ +plinth.modules.i2p diff --git a/plinth/modules/diagnostics/urls.py b/plinth/modules/diagnostics/urls.py index 7e31b8a22..56ff7ef0b 100644 --- a/plinth/modules/diagnostics/urls.py +++ b/plinth/modules/diagnostics/urls.py @@ -26,6 +26,6 @@ from . import diagnostics as views urlpatterns = [ url(r'^sys/diagnostics/$', views.index, name='index'), - url(r'^sys/diagnostics/(?P[a-z\-]+)/$', views.module, + url(r'^sys/diagnostics/(?P[1-9a-z\-]+)/$', views.module, name='module'), ] diff --git a/plinth/modules/i2p/__init__.py b/plinth/modules/i2p/__init__.py new file mode 100644 index 000000000..65eb3e170 --- /dev/null +++ b/plinth/modules/i2p/__init__.py @@ -0,0 +1,132 @@ +# +# 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 . +# +""" +FreedomBox app to configure I2P. +""" + +from django.utils.translation import ugettext_lazy as _ + +from plinth import action_utils, actions, frontpage +from plinth import service as service_module +from plinth.menu import main_menu +from plinth.modules.users import register_group +from .manifest import backup, clients + +version = 1 + +servicename = 'i2p' + +managed_services = [servicename] + +managed_packages = ['i2p'] + +name = _('I2P') + +short_description = _('Anonymity Network') + +description = [ + _('I2P is an anonymous overlay network - a network within a network. ' + 'It is intended to protect communication from dragnet surveillance ' + 'and monitoring by third parties such as ISPs. '), + _('When enabled, I2P\'s web interface will be available from ' + '/i2p.'), +] + +clients = clients + +group = ('i2p', _('Manage I2P application')) + +service = None + +manual_page = 'I2P' + + +def init(): + """Intialize the module.""" + menu = main_menu.get('apps') + menu.add_urlname(name, 'i2p', 'i2p:index', + short_description) + register_group(group) + + 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) + + if is_enabled(): + add_shortcut() + + +def setup(helper, old_version=None): + """Install and configure the module.""" + + helper.install(managed_packages) + helper.call('post', action_utils.webserver_enable, "proxy_html", kind="module") + 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) + helper.call('post', add_shortcut) + + +def add_shortcut(): + """Helper method to add a shortcut to the frontpage.""" + frontpage.add_shortcut('i2p', name, + short_description=short_description, + url='/i2p/', login_required=True, + allowed_groups=[group[0]]) + + +def is_running(): + """Return whether the service is running.""" + return action_utils.service_is_running("i2p") + + +def is_enabled(): + """Return whether the module is enabled.""" + return action_utils.service_is_enabled("i2p") and action_utils.webserver_is_enabled("i2p-plinth") + + +def enable(): + """Enable the module.""" + actions.superuser_run("i2p", ["enable"]) + add_shortcut() + + +def disable(): + """Enable the module.""" + actions.superuser_run("i2p", ["disable"]) + frontpage.remove_shortcut('i2p') + + +def diagnose(): + """Run diagnostics and return the results.""" + results = [] + + results.extend( + action_utils.diagnose_url_on_all('https://{host}/i2p/', + check_certificate=False)) + + return results diff --git a/plinth/modules/i2p/manifest.py b/plinth/modules/i2p/manifest.py new file mode 100644 index 000000000..33de80dc2 --- /dev/null +++ b/plinth/modules/i2p/manifest.py @@ -0,0 +1,55 @@ +# +# 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 . +# + +from django.utils.translation import ugettext_lazy as _ + +from plinth.clients import validate +from plinth.modules.backups.api import validate as validate_backup + +_package_id = 'net.geti2p.i2p' +_download_url = 'https://geti2p.net/download' + +clients = validate([{ + 'name': + _('I2P'), + 'platforms': [ + { + 'type': 'package', + 'format': 'deb', + 'name': 'i2p', + }, { + 'type': 'download', + 'os': 'gnu-linux', + 'url': _download_url, + }, { + 'type': 'download', + 'os': 'macos', + 'url': _download_url, + }, { + 'type': 'download', + 'os': 'windows', + 'url': _download_url, + } + ] +}]) + +backup = validate_backup({ + 'secrets': { + 'directories': ['/var/lib/i2p/.config'] + }, + 'services': ['i2p'] +}) diff --git a/plinth/modules/i2p/urls.py b/plinth/modules/i2p/urls.py new file mode 100644 index 000000000..f2646e328 --- /dev/null +++ b/plinth/modules/i2p/urls.py @@ -0,0 +1,34 @@ +# +# 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 . +# +""" +URLs for the I2P module. +""" + +from django.conf.urls import url + +from plinth.modules import i2p +from plinth.views import ServiceView + +urlpatterns = [ + url(r'^apps/i2p/$', + ServiceView.as_view( + service_id=i2p.managed_services[0], + diagnostics_module_name='i2p', + description=i2p.description, clients=i2p.clients, + manual_page=i2p.manual_page, show_status_block=True), + name='index'), +] diff --git a/static/themes/default/icons/i2p.png b/static/themes/default/icons/i2p.png new file mode 100644 index 000000000..2e5d69b1a Binary files /dev/null and b/static/themes/default/icons/i2p.png differ