From b7e44eb42926ca59d8309265015b5da6a0901f09 Mon Sep 17 00:00:00 2001 From: James Valleroy Date: Fri, 8 Jan 2016 19:56:31 -0500 Subject: [PATCH] Add repro SIP proxy module. --- actions/repro | 84 +++++++++++++++++++ .../apache2/conf-available/repro-plinth.conf | 11 +++ data/etc/plinth/modules-enabled/repro | 1 + .../lib/firewalld/services/repro-plinth.xml | 8 ++ plinth/modules/repro/__init__.py | 66 +++++++++++++++ plinth/modules/repro/forms.py | 30 +++++++ plinth/modules/repro/templates/repro.html | 80 ++++++++++++++++++ plinth/modules/repro/tests/__init__.py | 0 plinth/modules/repro/urls.py | 29 +++++++ plinth/modules/repro/views.py | 79 +++++++++++++++++ 10 files changed, 388 insertions(+) create mode 100755 actions/repro create mode 100644 data/etc/apache2/conf-available/repro-plinth.conf create mode 100644 data/etc/plinth/modules-enabled/repro create mode 100644 data/usr/lib/firewalld/services/repro-plinth.xml create mode 100644 plinth/modules/repro/__init__.py create mode 100644 plinth/modules/repro/forms.py create mode 100644 plinth/modules/repro/templates/repro.html create mode 100644 plinth/modules/repro/tests/__init__.py create mode 100644 plinth/modules/repro/urls.py create mode 100644 plinth/modules/repro/views.py diff --git a/actions/repro b/actions/repro new file mode 100755 index 000000000..0cd2edbe2 --- /dev/null +++ b/actions/repro @@ -0,0 +1,84 @@ +#!/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 . +# + +""" +Configuration helper for repro SIP proxy. +""" + +import argparse + +from plinth import action_utils + +CONFIG = '/etc/repro/repro.config' + + +def parse_arguments(): + """Return parsed command line arguments as dictionary.""" + parser = argparse.ArgumentParser() + subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') + + subparsers.add_parser('setup', help='Configure repro') + subparsers.add_parser('enable', help='Enable repro service') + subparsers.add_parser('disable', help='Disable repro service') + + return parser.parse_args() + + +def subcommand_setup(_): + """Configure repro.""" + with open(CONFIG, 'r') as conf: + lines = conf.readlines() + + with open(CONFIG, 'w') as conf: + for line in lines: + if line.startswith('Database1Path'): + # workaround for Debian bug #803113 + conf.write('Database1Path = /var/lib/repro\n') + elif line.startswith('TLSPort'): + conf.write('TLSPort = 5061\n') + elif line.startswith('DisableHttpAuth'): + # let apache handle authentication + conf.write('DisableHttpAuth = true\n') + else: + conf.write(line) + + action_utils.service_restart('repro') + action_utils.webserver_enable('repro-plinth') + + +def subcommand_enable(_): + """Start service.""" + action_utils.service_enable('repro') + + +def subcommand_disable(_): + """Stop service.""" + action_utils.service_disable('repro') + + +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() diff --git a/data/etc/apache2/conf-available/repro-plinth.conf b/data/etc/apache2/conf-available/repro-plinth.conf new file mode 100644 index 000000000..e7b0c38d9 --- /dev/null +++ b/data/etc/apache2/conf-available/repro-plinth.conf @@ -0,0 +1,11 @@ + + ProxyPass http://localhost:5080 + + AuthType basic + AuthName "FreedomBox Login" + AuthBasicProvider ldap + AuthLDAPUrl "ldap:///ou=users,dc=thisbox?uid" + AuthLDAPGroupAttribute memberUid + AuthLDAPGroupAttributeIsDN off + Require ldap-group cn=admin,ou=groups,dc=thisbox + diff --git a/data/etc/plinth/modules-enabled/repro b/data/etc/plinth/modules-enabled/repro new file mode 100644 index 000000000..38592b66d --- /dev/null +++ b/data/etc/plinth/modules-enabled/repro @@ -0,0 +1 @@ +plinth.modules.repro diff --git a/data/usr/lib/firewalld/services/repro-plinth.xml b/data/usr/lib/firewalld/services/repro-plinth.xml new file mode 100644 index 000000000..2abc90c41 --- /dev/null +++ b/data/usr/lib/firewalld/services/repro-plinth.xml @@ -0,0 +1,8 @@ + + + repro SIP proxy + repro is a SIP proxy server. It provides authentication, authorization, and call routing features. + + + + diff --git a/plinth/modules/repro/__init__.py b/plinth/modules/repro/__init__.py new file mode 100644 index 000000000..d7dc17bd7 --- /dev/null +++ b/plinth/modules/repro/__init__.py @@ -0,0 +1,66 @@ +# +# 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 . +# + +""" +Plinth module for repro. +""" + +from django.utils.translation import ugettext_lazy as _ + +from plinth import action_utils +from plinth import cfg +from plinth import service as service_module + +depends = ['plinth.modules.apps'] + +service = None + + +def init(): + """Initialize the repro module.""" + menu = cfg.main_menu.get('apps:index') + menu.add_urlname(_('SIP Proxy (Repro)'), 'glyphicon-phone-alt', + 'repro:index', 800) + + global service + service = service_module.Service( + 'repro', _('Repro SIP Proxy'), + is_external=True, enabled=is_enabled()) + + +def is_enabled(): + """Return whether the service is enabled.""" + return action_utils.service_is_enabled('repro') + + +def is_running(): + """Return whether the service is running.""" + return action_utils.service_is_running('repro') + + +def diagnose(): + """Run diagnostics and return the results.""" + results = [] + + results.append(action_utils.diagnose_port_listening(5060, 'udp4')) + results.append(action_utils.diagnose_port_listening(5060, 'udp6')) + results.append(action_utils.diagnose_port_listening(5060, 'tcp4')) + results.append(action_utils.diagnose_port_listening(5060, 'tcp6')) + results.append(action_utils.diagnose_port_listening(5061, 'tcp4')) + results.append(action_utils.diagnose_port_listening(5061, 'tcp6')) + + return results diff --git a/plinth/modules/repro/forms.py b/plinth/modules/repro/forms.py new file mode 100644 index 000000000..1fd313222 --- /dev/null +++ b/plinth/modules/repro/forms.py @@ -0,0 +1,30 @@ +# +# 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 . +# + +""" +Forms for repro module. +""" + +from django import forms +from django.utils.translation import ugettext_lazy as _ + + +class ReproForm(forms.Form): + """Configuration form.""" + enabled = forms.BooleanField( + label=_('Enable Repro service'), + required=False) diff --git a/plinth/modules/repro/templates/repro.html b/plinth/modules/repro/templates/repro.html new file mode 100644 index 000000000..c6df8731c --- /dev/null +++ b/plinth/modules/repro/templates/repro.html @@ -0,0 +1,80 @@ +{% 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 . +# +{% endcomment %} + +{% load bootstrap %} +{% load i18n %} + +{% block content %} + +

{% trans "SIP Proxy (Repro)" %}

+ +

+ {% blocktrans trimmed %} + Repro is a SIP proxy service that a SIP softphone can connect to. Before + using Repro, the domain and users will need to be configured using the + web-based configuration panel, available at + /repro/domains.html. Users in the + admin group will be able to log in to the Repro configuration panel. + {% endblocktrans %} +

+ +

+ {% blocktrans trimmed %} + Note: After setting the domain, it is required to restart the Repro + service. Disable the service using the checkbox and Update setup button + below. Then, re-enable the service. + {% endblocktrans %} +

+ +

+ {% blocktrans trimmed %} + To make SIP calls, a client application is needed. Available clients include + Jitsi (for computers) and + + CSipSimple (for Android phones). + {% endblocktrans %} +

+ +

{% trans "Status" %}

+ +

+ {% if status.is_running %} + + {% trans "Repro service is running" %} + {% else %} + + {% trans "Repro service is not running" %} + {% endif %} +

+ +{% include "diagnostics_button.html" with module="repro" %} + +

{% trans "Configuration" %}

+ +
+ {% csrf_token %} + + {{ form|bootstrap }} + + +
+ +{% endblock %} diff --git a/plinth/modules/repro/tests/__init__.py b/plinth/modules/repro/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/plinth/modules/repro/urls.py b/plinth/modules/repro/urls.py new file mode 100644 index 000000000..d87f8136b --- /dev/null +++ b/plinth/modules/repro/urls.py @@ -0,0 +1,29 @@ +# +# 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 . +# + +""" +URLs for the repro module. +""" + +from django.conf.urls import url + +from . import views + + +urlpatterns = [ + url(r'^apps/repro/$', views.index, name='index'), +] diff --git a/plinth/modules/repro/views.py b/plinth/modules/repro/views.py new file mode 100644 index 000000000..3b3bbe506 --- /dev/null +++ b/plinth/modules/repro/views.py @@ -0,0 +1,79 @@ +# +# 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 . +# + +""" +Views for repro module. +""" + +from django.contrib import messages +from django.template.response import TemplateResponse +from django.utils.translation import ugettext as _ + +from .forms import ReproForm +from plinth import actions +from plinth import package +from plinth.modules import repro + + +def on_install(): + """Notify that the service is now enabled.""" + actions.superuser_run('repro', ['setup']) + repro.service.notify_enabled(None, True) + + +@package.required(['repro'], on_install=on_install) +def index(request): + """Serve configuration page.""" + status = get_status() + + form = None + + if request.method == 'POST': + form = ReproForm(request.POST, prefix='repro') + if form.is_valid(): + _apply_changes(request, status, form.cleaned_data) + status = get_status() + form = ReproForm(initial=status, prefix='repro') + else: + form = ReproForm(initial=status, prefix='repro') + + return TemplateResponse(request, 'repro.html', + {'title': _('SIP Proxy (Repro)'), + 'status': status, + 'form': form}) + + +def get_status(): + """Get the current service status.""" + return {'enabled': repro.is_enabled(), + 'is_running': repro.is_running()} + + +def _apply_changes(request, old_status, new_status): + """Apply the changes.""" + modified = False + + if old_status['enabled'] != new_status['enabled']: + sub_command = 'enable' if new_status['enabled'] else 'disable' + actions.superuser_run('repro', [sub_command]) + repro.service.notify_enabled(None, new_status['enabled']) + modified = True + + if modified: + messages.success(request, _('Configuration updated')) + else: + messages.info(request, _('Setting unchanged'))