From 56208e007db9d754607caa360c47a65ffc89eafb Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Sun, 4 Jan 2015 12:14:23 +0000 Subject: [PATCH 001/103] added a module and a action script to manage ez-ipupdate tool, which provides dynamic IP updates to a gnudip dynamic DNS Server --- actions/dynamicDNS | 261 ++++++++++++++++++ data/etc/plinth/modules-enabled/dynamicDNS | 1 + plinth/modules/dynamicDNS/__init__.py | 27 ++ plinth/modules/dynamicDNS/dynamicDNS.py | 245 ++++++++++++++++ .../dynamicDNS/templates/dynamicDNS.html | 42 +++ .../templates/dynamicDNS_configure.html | 34 +++ .../templates/dynamicDNS_status.html | 42 +++ plinth/modules/dynamicDNS/urls.py | 30 ++ 8 files changed, 682 insertions(+) create mode 100755 actions/dynamicDNS create mode 100644 data/etc/plinth/modules-enabled/dynamicDNS create mode 100644 plinth/modules/dynamicDNS/__init__.py create mode 100644 plinth/modules/dynamicDNS/dynamicDNS.py create mode 100644 plinth/modules/dynamicDNS/templates/dynamicDNS.html create mode 100644 plinth/modules/dynamicDNS/templates/dynamicDNS_configure.html create mode 100755 plinth/modules/dynamicDNS/templates/dynamicDNS_status.html create mode 100644 plinth/modules/dynamicDNS/urls.py diff --git a/actions/dynamicDNS b/actions/dynamicDNS new file mode 100755 index 000000000..4350922bb --- /dev/null +++ b/actions/dynamicDNS @@ -0,0 +1,261 @@ +#!/bin/bash +#Todo: IPv6 +#Todo: Other service types than gnudip (generic update URL) +#Todo: GET WAN IP from Router via UPnP if supported + +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin + +#static values +EMPTYSTRING="none" +NOIP="0.0.0.0" +#how often do we poll for IP changes if we are behind a NAT? +UPDATEMINUTES=5 +#if we do not have a IP check URL, how often should we do a "blind" update +UPDATEMINUTESUNKNOWN=3600 +TOOLNAME=ez-ipupdate +UPDATE_TOOL=$(which ${TOOLNAME}) + +#Dirs and filenames +CFGDIR="/etc/${TOOLNAME}/" +CFG="${CFGDIR}${TOOLNAME}.conf" +CFG_disabled="${CFGDIR}${TOOLNAME}.inactive" +IPFILE="${CFGDIR}${TOOLNAME}.currentIP" +STATUSFILE="${CFGDIR}${TOOLNAME}.status" +LASTUPDATE="${CFGDIR}/last-update" +HELPERCFG="${CFGDIR}${TOOLNAME}-plinth.cfg" +CRONJOB="/etc/cron.d/${TOOLNAME}" + +doReadCFG() +{ + host="" + server="" + user="" + pass="" + IPURL="" + FILE="" + [ -f $CFG_disabled ] && FILE=$CFG_disabled + [ -f $CFG ] && FILE=$CFG + + if [ ! -z $FILE ];then + host=`cat $FILE 2> /dev/null |grep host |cut -d = -f 2` + server=`cat $FILE 2> /dev/null |grep server |cut -d = -f 2` + user=`cat $FILE 2> /dev/null |grep user |cut -d = -f 2 |cut -d : -f 1` + pass=`cat $FILE 2> /dev/null |grep user |cut -d = -f 2 |cut -d : -f 2` + fi + + if [ ! -z $HELPERCFG ];then + IPURL=`cat $HELPERCFG 2> /dev/null |grep URL |awk '{print $2}'` + fi +} + +doGetOpt() +{ + while getopts ":s:d:u:p:I:" opt; do + case $opt in + s) + server=$OPTARG + ;; + d) + host=$OPTARG + ;; + u) + user=$OPTARG + ;; + p) + pass=$OPTARG + ;; + I) + if [ "$OPTARG" != "$EMPTYSTRING" ];then + IPURL=$OPTARG + else + IPURL="" + fi + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + exit 1 + ;; + :) + echo "Option -$OPTARG requires an argument." >&2 + exit 1 + ;; + esac + done +} + +doWriteCFG() +{ + #always write to the inactive config - needs to be enabled vi "start" command later + FILE=$CFG_disabled + + #reset the last update time + echo 0 > $LASTUPDATE + + #reset the last updated IP + echo "0.0.0.0" > $IPFILE + + #reset last update + rm $STATUSFILE + + #find the interface (always the default gateway interface) + DEFAULT=`ip route |grep default |awk '{print $5}'` + + #store the given options in ez-ipupdate compatible config file + echo "host=$host" > $FILE + echo "server=$server" >> $FILE + echo "user=${user}:${pass}" >> $FILE + echo "service-type=gnudip" >> $FILE + echo "retrys=5" >> $FILE + echo "execute=$0 success" >> $FILE + echo "wildcard" >> $FILE + + #check if we are behind a NAT Router + echo "IPURL $IPURL" > $HELPERCFG + if [ -z $IPURL ];then + echo "NAT unknown" >> $HELPERCFG + else + doGetWANIP + ISGLOBAL=`ip addr ls $DEFAULT | grep $WANIP` + if [ -z $ISGLOBAL ];then + #we are behind NAT + echo "NAT yes" >> $HELPERCFG + else + #we are directly connected + echo "NAT no" >> $HELPERCFG + #if this file is added ez-ipupdate will take ip form this interface + echo "interface=$DEFAULT" >> $FILE + #if this line is added to config file, ez-ipupdate will be launched on startup via init.d + echo "daemon" >> $FILE + fi + fi +} + +doGetWANIP() +{ + if [ $IPURL ];then + OUTFILE=`mktemp` + wget -4 -o /dev/null -O $OUTFILE $IPURL + WANIP=`cat $OUTFILE` + rm $OUTFILE + else + #no WAN IP found because of missing check URL + WANIP=${NOIP} + fi + echo $WANIP > $IPFILE +} + +cmd=$1 +shift +case $cmd in + configure) + doGetOpt $@ + doWriteCFG + ;; + start) + if [ "$(cat $HELPERCFG |grep ^NAT | awk '{print $2}')" = "no" ];then + mv $CFG_disabled $CFG + /etc/init.d/${TOOLNAME} start + else + echo "*/${UPDATEMINUTES} * * * * root $0 update" > $CRONJOB + $0 update + fi + ;; + get-nat) + NAT=`cat $HELPERCFG 2> /dev/null |grep ^NAT | awk '{print $2}'` + [ -z $NAT ] && NAT="unknown" + echo $NAT + ;; + update) + doReadCFG + OLDIP=`cat $IPFILE` + doGetWANIP + [ -f $CFG_disabled ] && FILE=$CFG_disabled + [ -f $CFG ] && FILE=$CFG + RESULT=0 + #if we know our WAN IP, only update if IP changes + if [ "$OLDIP" != "$WANIP" -a "${WANIP}" != ${NOIP} ];then + ${UPDATE_TOOL} -c $FILE + RESULT=$? + cat /proc/uptime |awk '{print $1}' > $LASTUPDATE + fi + #if we don't know our WAN IP do a blind update once a hour + if [ "${WANIP}" = ${NOIP} ];then + UPTIME=`cat /proc/uptime` + LAST=`cat $LASTUPDATE` + DIFF=`expr $UPTIME - $LAST` + if [ $DIFF -gt $UPDATEMINUTESUNKNOWN ];then + ${UPDATE_TOOL} -c $FILE + RESULT=$? + cat /proc/uptime |awk '{print $1}' > $LASTUPDATE + fi + fi + if [ $RESULT -eq 0 ];then + $0 success + else + $0 failed + fi + ;; + stop) + rm $CRONJOB 2> /dev/null + /etc/init.d/${TOOLNAME} stop + mv $CFG $CFG_disabled + ;; + success) + DATE=`date` + echo "last update done ($DATE)" > $STATUSFILE + ;; + failed) + DATE=`date` + echo "last update failed ($DATE)" > $STATUSFILE + ;; + get-last-success) + if [ -f $STATUSFILE ];then + cat $STATUSFILE + else + echo "no update recorded since last config change" + fi + ;; + get-installed) + if [ ! -z ${UPDATE_TOOL} ];then + echo "installed" + fi + ;; + status) + doReadCFG + PROC=`pgrep ${TOOLNAME}` + if [ -f $CRONJOB ];then + echo enabled + elif [ ! -z $PROC ];then + echo enabled + else + echo disabled + fi + echo $server + echo $host + echo $user + echo $pass + echo $IPURL + ;; + get-timer) + echo $UPDATEMINUTES + ;; + clean) + rm ${CFGDIR}/* + ;; + *) + echo "usage: get-installed|status|configure |start|stop|update|get-nat|clean|success|failed" + echo "" + echo "options are:" + echo "-s Gnudip Server address" + echo "-d Domain to be updated" + echo "-u Account username" + echo "-p Account Password" + echo "-I A URL which returns the IP of the client who is requesting" + echo "" + echo "update do a one time update" + echo "clean delete configuration" + echo "success store update success" + echo "failed store update failure" + ;; +esac +exit 0 diff --git a/data/etc/plinth/modules-enabled/dynamicDNS b/data/etc/plinth/modules-enabled/dynamicDNS new file mode 100644 index 000000000..aaea9c4e7 --- /dev/null +++ b/data/etc/plinth/modules-enabled/dynamicDNS @@ -0,0 +1 @@ +plinth.modules.dynamicDNS diff --git a/plinth/modules/dynamicDNS/__init__.py b/plinth/modules/dynamicDNS/__init__.py new file mode 100644 index 000000000..992a11b42 --- /dev/null +++ b/plinth/modules/dynamicDNS/__init__.py @@ -0,0 +1,27 @@ +# +# 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 to configure XMPP server +""" + +from . import dynamicDNS +from .dynamicDNS import init + +__all__ = ['xmpp2', 'init'] + +depends = ['plinth.modules.apps'] diff --git a/plinth/modules/dynamicDNS/dynamicDNS.py b/plinth/modules/dynamicDNS/dynamicDNS.py new file mode 100644 index 000000000..780d18676 --- /dev/null +++ b/plinth/modules/dynamicDNS/dynamicDNS.py @@ -0,0 +1,245 @@ +# +# 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 . +# + +from django import forms +from django.contrib import messages +from django.contrib.auth.decorators import login_required +from django.core import validators +from django.core.urlresolvers import reverse_lazy +from django.template.response import TemplateResponse +from gettext import gettext as _ +import logging + +from plinth import actions +from plinth import cfg + +LOGGER = logging.getLogger(__name__) + +subsubmenu = [{'url': reverse_lazy('dynamicDNS:index'), + 'text': _('About')}, + {'url': reverse_lazy('dynamicDNS:configure'), + 'text': _('Configure')}, + {'url': reverse_lazy('dynamicDNS:statuspage'), + 'text': _('Status')} + ] + +def init(): + """Initialize the dynamicDNS module""" + menu = cfg.main_menu.get('apps:index') + menu.add_urlname('dynamicDNS', 'glyphicon-comment', 'dynamicDNS:index', 40) + +@login_required +def index(request): + """Serve dynamic DNS page""" + + is_installed = actions.run('dynamicDNS', ['get-installed']).strip() == 'installed' + + if is_installed: + index_subsubmenu = subsubmenu + else: + index_subsubmenu = None + + return TemplateResponse(request, 'dynamicDNS.html', + {'title': _('dynamicDNS'), + 'is_installed': is_installed, + 'subsubmenu': index_subsubmenu}) + +class TrimmedCharField(forms.CharField): + """Trim the contents of a CharField""" + def clean(self, value): + """Clean and validate the field value""" + if value: + value = value.strip() + + return super(TrimmedCharField, self).clean(value) + +class ConfigureForm(forms.Form): + """Form to configure the dynamic DNS client""" + enabled = forms.BooleanField(label=_('Enable dynamicDNS'), + required=False) + + dynamicDNS_Server = TrimmedCharField( + label=_('Server Address'), + help_text=_('Example: gnudip.provider.org'), + validators=[ + validators.RegexValidator(r'^[\w-]{1,63}(\.[\w-]{1,63})*$', + _('Invalid server name'))]) + + dynamicDNS_Domain = TrimmedCharField( + label=_('Domain Name'), + help_text=_('Example: hostname.sds-ip.de'), + validators=[ + validators.RegexValidator(r'^[\w-]{1,63}(\.[\w-]{1,63})*$', + _('Invalid domain name'))]) + + dynamicDNS_User = TrimmedCharField( + label=_('Username'), + help_text=_('You should have been requested to select a username when you created the account')) + + dynamicDNS_Secret = TrimmedCharField( + label=_('Password'), widget=forms.PasswordInput(), + required=False, + help_text=_('You should have been requested to select a password when you created the account. \ + If you left this field empty your password will be unchanged.')) + + dynamicDNS_Secret_repeat = TrimmedCharField( + label=_('repeat Password'), widget=forms.PasswordInput(), + required=False, + help_text=_('insert the password twice to avoid typos. If you left this field empty your password \ + will be unchanged.'),) + + dynamicDNS_IPURL = TrimmedCharField( + label=_('IP check URL'), + required=False, + help_text=_('Optional Value. If your FreedomBox is not connected directly to the Internet (i.e. \ + connected to a NAT router) this URL is used to figure out the real Internet IP. The URL should \ + simply return the IP where the client comes from. Example: http://myip.datasystems24.de'), + validators=[ + validators.URLValidator(schemes=['http','https','ftp'])]) + +@login_required +def configure(request): + """Serve the configuration form""" + status = get_status() + form = None + + if request.method == 'POST': + form = ConfigureForm(request.POST, prefix='dynamicDNS') + if form.is_valid(): + _apply_changes(request, status, form.cleaned_data) + status = get_status() + form = ConfigureForm(initial=status, prefix='dynamicDNS') + else: + form = ConfigureForm(initial=status, prefix='dynamicDNS') + + return TemplateResponse(request, 'dynamicDNS_configure.html', + {'title': _('Configure dynamicDNS Client'), + 'form': form, + 'subsubmenu': subsubmenu}) + +@login_required +def statuspage(request): + """Serve the status page """ + check_NAT = actions.run('dynamicDNS', ['get-nat']) + last_update = actions.run('dynamicDNS', ['get-last-success']) + + no_NAT = check_NAT.strip() == 'no' + NAT_unchecked = check_NAT.strip() == 'unknown' + timer = actions.run('dynamicDNS', ['get-timer']) + + if no_NAT: + LOGGER.info('we are not behind a NAT') + + if NAT_unchecked: + LOGGER.info('we did not checked if we are behind a NAT') + + return TemplateResponse(request, 'dynamicDNS_status.html', + {'title': _('Status of dynamicDNS Client'), + 'no_NAT': no_NAT, + 'NAT_unchecked' : NAT_unchecked, + 'timer' : timer, + 'last_update' : last_update, + 'subsubmenu': subsubmenu}) + +def get_status(): + """Return the current status""" + """ToDo: use key/value instead of hard coded value list""" + status = {} + output = actions.run('dynamicDNS', 'status') + details = output.split() + status['enabled'] = (output.split()[0] == 'enabled') + if len(details) > 1: + status['dynamicDNS_Server'] = details[1] + else: + status['dynamicDNS_Server'] = '' + + if len(details) > 2: + status['dynamicDNS_Domain'] = details[2] + else: + status['dynamicDNS_Domain'] = '' + + if len(details) > 3: + status['dynamicDNS_User'] = details[3] + else: + status['dynamicDNS_User'] = '' + + if len(details) > 4: + status['dynamicDNS_Secret'] = details[4] + else: + status['dynamicDNS_Secret'] = '' + + if len(details) > 5: + status['dynamicDNS_IPURL'] = details[5] + else: + status['dynamicDNS_Secret'] = '' + + return status + +def _apply_changes(request, old_status, new_status): + """Apply the changes to Dynamic DNS client""" + LOGGER.info('New status is - %s', new_status) + LOGGER.info('Old status was - %s', old_status) + FAIL = False + + if new_status['dynamicDNS_Secret_repeat'] != new_status['dynamicDNS_Secret']: + messages.error(request, _('passwords does not match')) + FAIL = True + + if old_status['dynamicDNS_Secret'] == '' and new_status['dynamicDNS_Secret'] == '': + messages.error(request, _('please give a password')) + FAIL = True + + if False == FAIL: + if new_status['dynamicDNS_Secret'] == '': + new_status['dynamicDNS_Secret'] = old_status['dynamicDNS_Secret'] + + if new_status['dynamicDNS_IPURL'] == '': + new_status['dynamicDNS_IPURL'] = 'none' + + if old_status['dynamicDNS_Server'] != new_status['dynamicDNS_Server'] or \ + old_status['dynamicDNS_Domain'] != new_status['dynamicDNS_Domain'] or \ + old_status['dynamicDNS_User'] != new_status['dynamicDNS_User'] or \ + old_status['dynamicDNS_Secret'] != new_status['dynamicDNS_Secret'] or \ + old_status['dynamicDNS_IPURL'] != new_status['dynamicDNS_IPURL']: + + _run(['configure', '-s', new_status['dynamicDNS_Server'], + '-d', new_status['dynamicDNS_Domain'], + '-u', new_status['dynamicDNS_User'], + '-p', new_status['dynamicDNS_Secret'], + '-I', new_status['dynamicDNS_IPURL']]) + _run(['stop']) + _run(['start']) + messages.success(request, _('Dynamic DNS configuration is updated!')) + + if old_status['enabled'] != new_status['enabled']: + if new_status['enabled']: + _run(['start']) + messages.success(request, _('Dynamic DNS is enabled now!')) + else: + _run(['stop']) + messages.success(request, _('Dynamic DNS is disabled now!')) + else: + messages.error(request, _('At least on failure occured, please check your input.')) + +def _run(arguments, superuser=False): + """Run a given command and raise exception if there was an error""" + command = 'dynamicDNS' + + if superuser: + return actions.superuser_run(command, arguments) + else: + return actions.run(command, arguments) diff --git a/plinth/modules/dynamicDNS/templates/dynamicDNS.html b/plinth/modules/dynamicDNS/templates/dynamicDNS.html new file mode 100644 index 000000000..44607d12d --- /dev/null +++ b/plinth/modules/dynamicDNS/templates/dynamicDNS.html @@ -0,0 +1,42 @@ +{% 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 %} + +{% block content %} + +{% if is_installed %} + +

If your internet provider changes your IP address periodic (i.e. every 24h) it may be hard for others to find you in the WEB. And for this reason nobody may find the services which are provided by freedombox (like your owncloud). The solution is to assign a DNS name to your IP address and update the DNS name every time your IP is changed by your Internet provider. Dynamic DNS allows you to push your current public IP address to an gnudip server. Afterwards the Server will assign your personal DNS name with the new IP and if someone from the internet asks for your DNS name he will get your personal IP answered.

+ +{% else %} + +

DynamicDNS client

+ +

The Dynamic DNS tool ez-ipupdate is not installed.

+ +

ez-ipupdate comes pre-installed with {{ cfg.box_name }}. On any Debian-based + system (such as {{ cfg.box_name }}) you may install it using the command + apt-get install ez-ipupdate.

+ +{% endif %} + +{% endblock %} diff --git a/plinth/modules/dynamicDNS/templates/dynamicDNS_configure.html b/plinth/modules/dynamicDNS/templates/dynamicDNS_configure.html new file mode 100644 index 000000000..ade236ba9 --- /dev/null +++ b/plinth/modules/dynamicDNS/templates/dynamicDNS_configure.html @@ -0,0 +1,34 @@ +{% 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 %} + +{% block content %} +

Configuration

+
+ {% csrf_token %} + + {{ form|bootstrap }} + + + +
+ +{% endblock %} diff --git a/plinth/modules/dynamicDNS/templates/dynamicDNS_status.html b/plinth/modules/dynamicDNS/templates/dynamicDNS_status.html new file mode 100755 index 000000000..95f97dccf --- /dev/null +++ b/plinth/modules/dynamicDNS/templates/dynamicDNS_status.html @@ -0,0 +1,42 @@ +{% 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 %} + +{% block content %} +

+

NAT type

+ {% if NAT_unchecked %} + NAT type not detected yet, if you do not provide a "IP check URL" we will + not detect a NAT type. + {% else %} + {% if no_NAT %} + Direct connection to the internet. + {% else %} + Behind NAT, this means that dynamic DNS service will poll the + "IP check URL" for changes (we need the "IP check URL" for this reason - otherwise we will not detect IP changes). + It may take up to {{ timer }} minutes until we update your DNS entry in case of WAN IP change. + {% endif %} + {% endif %} +

Last update

+ {{ last_update }} +

+ +{% endblock %} diff --git a/plinth/modules/dynamicDNS/urls.py b/plinth/modules/dynamicDNS/urls.py new file mode 100644 index 000000000..61bab8ce2 --- /dev/null +++ b/plinth/modules/dynamicDNS/urls.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 . +# + +""" +URLs for the DynamicDNS module +""" + +from django.conf.urls import patterns, url + + +urlpatterns = patterns( + 'plinth.modules.dynamicDNS.dynamicDNS', + url(r'^apps/dynamicDNS/$', 'index', name='index'), + url(r'^apps/dynamicDNS/configure/$', 'configure', name='configure'), + url(r'^apps/dynamicDNS/statuspage/$', 'statuspage', name='statuspage') +) From 3bf0079b3bbabd8d13f295c7075c22d1a32a4bf6 Mon Sep 17 00:00:00 2001 From: daniel steglich Date: Sun, 4 Jan 2015 13:50:26 +0100 Subject: [PATCH 002/103] pep8 coding guidline adaption --- plinth/modules/dynamicDNS/dynamicDNS.py | 117 ++++++++++++++---------- 1 file changed, 71 insertions(+), 46 deletions(-) diff --git a/plinth/modules/dynamicDNS/dynamicDNS.py b/plinth/modules/dynamicDNS/dynamicDNS.py index 780d18676..0e4d799a5 100644 --- a/plinth/modules/dynamicDNS/dynamicDNS.py +++ b/plinth/modules/dynamicDNS/dynamicDNS.py @@ -34,19 +34,22 @@ subsubmenu = [{'url': reverse_lazy('dynamicDNS:index'), {'url': reverse_lazy('dynamicDNS:configure'), 'text': _('Configure')}, {'url': reverse_lazy('dynamicDNS:statuspage'), - 'text': _('Status')} + 'text': _('Status')} ] + def init(): """Initialize the dynamicDNS module""" menu = cfg.main_menu.get('apps:index') menu.add_urlname('dynamicDNS', 'glyphicon-comment', 'dynamicDNS:index', 40) + @login_required def index(request): """Serve dynamic DNS page""" - - is_installed = actions.run('dynamicDNS', ['get-installed']).strip() == 'installed' + + is_installed = actions.run('dynamicDNS', ['get-installed']).strip() \ + == 'installed' if is_installed: index_subsubmenu = subsubmenu @@ -58,6 +61,7 @@ def index(request): 'is_installed': is_installed, 'subsubmenu': index_subsubmenu}) + class TrimmedCharField(forms.CharField): """Trim the contents of a CharField""" def clean(self, value): @@ -66,9 +70,10 @@ class TrimmedCharField(forms.CharField): value = value.strip() return super(TrimmedCharField, self).clean(value) - + + class ConfigureForm(forms.Form): - """Form to configure the dynamic DNS client""" + """Form to configure the dynamic DNS client""" enabled = forms.BooleanField(label=_('Enable dynamicDNS'), required=False) @@ -88,28 +93,34 @@ class ConfigureForm(forms.Form): dynamicDNS_User = TrimmedCharField( label=_('Username'), - help_text=_('You should have been requested to select a username when you created the account')) - + help_text=_('You should have been requested to select a username \ + when you created the account')) + dynamicDNS_Secret = TrimmedCharField( label=_('Password'), widget=forms.PasswordInput(), required=False, - help_text=_('You should have been requested to select a password when you created the account. \ - If you left this field empty your password will be unchanged.')) - + help_text=_('You should have been requested to select a password \ + when you created the account. If you left this field \ + empty your password will be unchanged.')) + dynamicDNS_Secret_repeat = TrimmedCharField( label=_('repeat Password'), widget=forms.PasswordInput(), required=False, - help_text=_('insert the password twice to avoid typos. If you left this field empty your password \ - will be unchanged.'),) + help_text=_('insert the password twice to avoid typos. If you left \ + this field empty your password will be unchanged.'),) dynamicDNS_IPURL = TrimmedCharField( label=_('IP check URL'), required=False, - help_text=_('Optional Value. If your FreedomBox is not connected directly to the Internet (i.e. \ - connected to a NAT router) this URL is used to figure out the real Internet IP. The URL should \ - simply return the IP where the client comes from. Example: http://myip.datasystems24.de'), + help_text=_('Optional Value. If your FreedomBox is not connected \ + directly to the Internet (i.e. connected to a NAT \ + router) this URL is used to figure out the real Internet \ + IP. The URL should simply return the IP where the \ + client comes from. Example: \ + http://myip.datasystems24.de'), validators=[ - validators.URLValidator(schemes=['http','https','ftp'])]) + validators.URLValidator(schemes=['http', 'https', 'ftp'])]) + @login_required def configure(request): @@ -131,30 +142,32 @@ def configure(request): 'form': form, 'subsubmenu': subsubmenu}) + @login_required def statuspage(request): """Serve the status page """ check_NAT = actions.run('dynamicDNS', ['get-nat']) last_update = actions.run('dynamicDNS', ['get-last-success']) - + no_NAT = check_NAT.strip() == 'no' NAT_unchecked = check_NAT.strip() == 'unknown' timer = actions.run('dynamicDNS', ['get-timer']) - + if no_NAT: LOGGER.info('we are not behind a NAT') - + if NAT_unchecked: LOGGER.info('we did not checked if we are behind a NAT') return TemplateResponse(request, 'dynamicDNS_status.html', {'title': _('Status of dynamicDNS Client'), 'no_NAT': no_NAT, - 'NAT_unchecked' : NAT_unchecked, - 'timer' : timer, - 'last_update' : last_update, + 'NAT_unchecked': NAT_unchecked, + 'timer': timer, + 'last_update': last_update, 'subsubmenu': subsubmenu}) + def get_status(): """Return the current status""" """ToDo: use key/value instead of hard coded value list""" @@ -166,65 +179,75 @@ def get_status(): status['dynamicDNS_Server'] = details[1] else: status['dynamicDNS_Server'] = '' - + if len(details) > 2: status['dynamicDNS_Domain'] = details[2] else: status['dynamicDNS_Domain'] = '' - + if len(details) > 3: status['dynamicDNS_User'] = details[3] else: status['dynamicDNS_User'] = '' - + if len(details) > 4: status['dynamicDNS_Secret'] = details[4] else: status['dynamicDNS_Secret'] = '' - + if len(details) > 5: status['dynamicDNS_IPURL'] = details[5] else: status['dynamicDNS_Secret'] = '' - + return status + def _apply_changes(request, old_status, new_status): """Apply the changes to Dynamic DNS client""" LOGGER.info('New status is - %s', new_status) LOGGER.info('Old status was - %s', old_status) FAIL = False - - if new_status['dynamicDNS_Secret_repeat'] != new_status['dynamicDNS_Secret']: + + if new_status['dynamicDNS_Secret_repeat'] != \ + new_status['dynamicDNS_Secret']: + messages.error(request, _('passwords does not match')) FAIL = True - - if old_status['dynamicDNS_Secret'] == '' and new_status['dynamicDNS_Secret'] == '': - messages.error(request, _('please give a password')) - FAIL = True - + + if old_status['dynamicDNS_Secret'] == '' and \ + new_status['dynamicDNS_Secret'] == '': + messages.error(request, _('please give a password')) + FAIL = True + if False == FAIL: if new_status['dynamicDNS_Secret'] == '': new_status['dynamicDNS_Secret'] = old_status['dynamicDNS_Secret'] - + if new_status['dynamicDNS_IPURL'] == '': new_status['dynamicDNS_IPURL'] = 'none' - - if old_status['dynamicDNS_Server'] != new_status['dynamicDNS_Server'] or \ - old_status['dynamicDNS_Domain'] != new_status['dynamicDNS_Domain'] or \ - old_status['dynamicDNS_User'] != new_status['dynamicDNS_User'] or \ - old_status['dynamicDNS_Secret'] != new_status['dynamicDNS_Secret'] or \ - old_status['dynamicDNS_IPURL'] != new_status['dynamicDNS_IPURL']: - + + if old_status['dynamicDNS_Server'] != \ + new_status['dynamicDNS_Server'] or \ + old_status['dynamicDNS_Domain'] != \ + new_status['dynamicDNS_Domain'] or \ + old_status['dynamicDNS_User'] != \ + new_status['dynamicDNS_User'] or \ + old_status['dynamicDNS_Secret'] != \ + new_status['dynamicDNS_Secret'] or \ + old_status['dynamicDNS_IPURL'] != \ + new_status['dynamicDNS_IPURL']: + _run(['configure', '-s', new_status['dynamicDNS_Server'], - '-d', new_status['dynamicDNS_Domain'], + '-d', new_status['dynamicDNS_Domain'], '-u', new_status['dynamicDNS_User'], '-p', new_status['dynamicDNS_Secret'], '-I', new_status['dynamicDNS_IPURL']]) _run(['stop']) _run(['start']) - messages.success(request, _('Dynamic DNS configuration is updated!')) - + messages.success(request, \ + _('Dynamic DNS configuration is updated!')) + if old_status['enabled'] != new_status['enabled']: if new_status['enabled']: _run(['start']) @@ -233,7 +256,9 @@ def _apply_changes(request, old_status, new_status): _run(['stop']) messages.success(request, _('Dynamic DNS is disabled now!')) else: - messages.error(request, _('At least on failure occured, please check your input.')) + messages.error(request, \ + _('At least on failure occured, please check your input.')) + def _run(arguments, superuser=False): """Run a given command and raise exception if there was an error""" From eb63f5c74f0729483d002bd8e5e54615ca1ce973 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Sun, 4 Jan 2015 13:53:29 +0100 Subject: [PATCH 003/103] pep8 coding guidline adaption --- plinth/modules/dynamicDNS/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plinth/modules/dynamicDNS/__init__.py b/plinth/modules/dynamicDNS/__init__.py index 992a11b42..c2b6cabec 100644 --- a/plinth/modules/dynamicDNS/__init__.py +++ b/plinth/modules/dynamicDNS/__init__.py @@ -16,12 +16,12 @@ # """ -Plinth module to configure XMPP server +Plinth module to configure ez-ipupdate client """ -from . import dynamicDNS +from . import dynamicDNS from .dynamicDNS import init -__all__ = ['xmpp2', 'init'] +__all__ = ['dynamicDNS', 'init'] depends = ['plinth.modules.apps'] From 375b591d7e3be0dc6436f757ac3fd373b7a20eaf Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Sun, 4 Jan 2015 13:55:01 +0100 Subject: [PATCH 004/103] fixed permissions --- plinth/modules/dynamicDNS/templates/dynamicDNS_status.html | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 plinth/modules/dynamicDNS/templates/dynamicDNS_status.html diff --git a/plinth/modules/dynamicDNS/templates/dynamicDNS_status.html b/plinth/modules/dynamicDNS/templates/dynamicDNS_status.html old mode 100755 new mode 100644 From 8e15511b44d91c30406c5921f447ef8110205304 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Sun, 4 Jan 2015 14:07:55 +0100 Subject: [PATCH 005/103] some pylint related adjustments --- plinth/modules/dynamicDNS/dynamicDNS.py | 22 +++++++++---------- .../templates/dynamicDNS_status.html | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/plinth/modules/dynamicDNS/dynamicDNS.py b/plinth/modules/dynamicDNS/dynamicDNS.py index 0e4d799a5..2a1f03780 100644 --- a/plinth/modules/dynamicDNS/dynamicDNS.py +++ b/plinth/modules/dynamicDNS/dynamicDNS.py @@ -146,23 +146,23 @@ def configure(request): @login_required def statuspage(request): """Serve the status page """ - check_NAT = actions.run('dynamicDNS', ['get-nat']) + check_nat = actions.run('dynamicDNS', ['get-nat']) last_update = actions.run('dynamicDNS', ['get-last-success']) - no_NAT = check_NAT.strip() == 'no' - NAT_unchecked = check_NAT.strip() == 'unknown' + no_nat = check_nat.strip() == 'no' + nat_unchecked = check_nat.strip() == 'unknown' timer = actions.run('dynamicDNS', ['get-timer']) - if no_NAT: + if no_nat: LOGGER.info('we are not behind a NAT') - if NAT_unchecked: + if nat_unchecked: LOGGER.info('we did not checked if we are behind a NAT') return TemplateResponse(request, 'dynamicDNS_status.html', {'title': _('Status of dynamicDNS Client'), - 'no_NAT': no_NAT, - 'NAT_unchecked': NAT_unchecked, + 'no_nat': no_nat, + 'nat_unchecked': nat_unchecked, 'timer': timer, 'last_update': last_update, 'subsubmenu': subsubmenu}) @@ -207,20 +207,20 @@ def _apply_changes(request, old_status, new_status): """Apply the changes to Dynamic DNS client""" LOGGER.info('New status is - %s', new_status) LOGGER.info('Old status was - %s', old_status) - FAIL = False + fail = False if new_status['dynamicDNS_Secret_repeat'] != \ new_status['dynamicDNS_Secret']: messages.error(request, _('passwords does not match')) - FAIL = True + fail = True if old_status['dynamicDNS_Secret'] == '' and \ new_status['dynamicDNS_Secret'] == '': messages.error(request, _('please give a password')) - FAIL = True + fail = True - if False == FAIL: + if False == fail: if new_status['dynamicDNS_Secret'] == '': new_status['dynamicDNS_Secret'] = old_status['dynamicDNS_Secret'] diff --git a/plinth/modules/dynamicDNS/templates/dynamicDNS_status.html b/plinth/modules/dynamicDNS/templates/dynamicDNS_status.html index 95f97dccf..c3608a512 100644 --- a/plinth/modules/dynamicDNS/templates/dynamicDNS_status.html +++ b/plinth/modules/dynamicDNS/templates/dynamicDNS_status.html @@ -23,11 +23,11 @@ {% block content %}

NAT type

- {% if NAT_unchecked %} + {% if nat_unchecked %} NAT type not detected yet, if you do not provide a "IP check URL" we will not detect a NAT type. {% else %} - {% if no_NAT %} + {% if no_nat %} Direct connection to the internet. {% else %} Behind NAT, this means that dynamic DNS service will poll the From af22962bbe2a49c2d0c12c1652628a46374dc82e Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Sun, 4 Jan 2015 14:28:02 +0100 Subject: [PATCH 006/103] fixed indentions --- actions/dynamicDNS | 248 ++++++++++++++++++++++----------------------- 1 file changed, 124 insertions(+), 124 deletions(-) diff --git a/actions/dynamicDNS b/actions/dynamicDNS index 4350922bb..fa1fe5a41 100755 --- a/actions/dynamicDNS +++ b/actions/dynamicDNS @@ -27,25 +27,25 @@ CRONJOB="/etc/cron.d/${TOOLNAME}" doReadCFG() { - host="" - server="" - user="" - pass="" - IPURL="" - FILE="" - [ -f $CFG_disabled ] && FILE=$CFG_disabled - [ -f $CFG ] && FILE=$CFG + host="" + server="" + user="" + pass="" + IPURL="" + FILE="" + [ -f $CFG_disabled ] && FILE=$CFG_disabled + [ -f $CFG ] && FILE=$CFG - if [ ! -z $FILE ];then - host=`cat $FILE 2> /dev/null |grep host |cut -d = -f 2` - server=`cat $FILE 2> /dev/null |grep server |cut -d = -f 2` - user=`cat $FILE 2> /dev/null |grep user |cut -d = -f 2 |cut -d : -f 1` - pass=`cat $FILE 2> /dev/null |grep user |cut -d = -f 2 |cut -d : -f 2` - fi + if [ ! -z $FILE ];then + host=`cat $FILE 2> /dev/null |grep host |cut -d = -f 2` + server=`cat $FILE 2> /dev/null |grep server |cut -d = -f 2` + user=`cat $FILE 2> /dev/null |grep user |cut -d = -f 2 |cut -d : -f 1` + pass=`cat $FILE 2> /dev/null |grep user |cut -d = -f 2 |cut -d : -f 2` + fi - if [ ! -z $HELPERCFG ];then - IPURL=`cat $HELPERCFG 2> /dev/null |grep URL |awk '{print $2}'` - fi + if [ ! -z $HELPERCFG ];then + IPURL=`cat $HELPERCFG 2> /dev/null |grep URL |awk '{print $2}'` + fi } doGetOpt() @@ -65,11 +65,11 @@ doGetOpt() pass=$OPTARG ;; I) - if [ "$OPTARG" != "$EMPTYSTRING" ];then - IPURL=$OPTARG - else - IPURL="" - fi + if [ "$OPTARG" != "$EMPTYSTRING" ];then + IPURL=$OPTARG + else + IPURL="" + fi ;; \?) echo "Invalid option: -$OPTARG" >&2 @@ -85,63 +85,63 @@ doGetOpt() doWriteCFG() { - #always write to the inactive config - needs to be enabled vi "start" command later - FILE=$CFG_disabled - - #reset the last update time - echo 0 > $LASTUPDATE - - #reset the last updated IP - echo "0.0.0.0" > $IPFILE - - #reset last update - rm $STATUSFILE - - #find the interface (always the default gateway interface) + #always write to the inactive config - needs to be enabled vi "start" command later + FILE=$CFG_disabled + + #reset the last update time + echo 0 > $LASTUPDATE + + #reset the last updated IP + echo "0.0.0.0" > $IPFILE + + #reset last update + rm $STATUSFILE + + #find the interface (always the default gateway interface) DEFAULT=`ip route |grep default |awk '{print $5}'` - + #store the given options in ez-ipupdate compatible config file echo "host=$host" > $FILE echo "server=$server" >> $FILE echo "user=${user}:${pass}" >> $FILE - echo "service-type=gnudip" >> $FILE - echo "retrys=5" >> $FILE - echo "execute=$0 success" >> $FILE - echo "wildcard" >> $FILE - - #check if we are behind a NAT Router + echo "service-type=gnudip" >> $FILE + echo "retrys=5" >> $FILE + echo "execute=$0 success" >> $FILE + echo "wildcard" >> $FILE + + #check if we are behind a NAT Router echo "IPURL $IPURL" > $HELPERCFG if [ -z $IPURL ];then - echo "NAT unknown" >> $HELPERCFG - else - doGetWANIP - ISGLOBAL=`ip addr ls $DEFAULT | grep $WANIP` - if [ -z $ISGLOBAL ];then - #we are behind NAT - echo "NAT yes" >> $HELPERCFG - else - #we are directly connected - echo "NAT no" >> $HELPERCFG - #if this file is added ez-ipupdate will take ip form this interface - echo "interface=$DEFAULT" >> $FILE - #if this line is added to config file, ez-ipupdate will be launched on startup via init.d - echo "daemon" >> $FILE - fi - fi + echo "NAT unknown" >> $HELPERCFG + else + doGetWANIP + ISGLOBAL=`ip addr ls $DEFAULT | grep $WANIP` + if [ -z $ISGLOBAL ];then + #we are behind NAT + echo "NAT yes" >> $HELPERCFG + else + #we are directly connected + echo "NAT no" >> $HELPERCFG + #if this file is added ez-ipupdate will take ip form this interface + echo "interface=$DEFAULT" >> $FILE + #if this line is added to config file, ez-ipupdate will be launched on startup via init.d + echo "daemon" >> $FILE + fi + fi } doGetWANIP() { - if [ $IPURL ];then - OUTFILE=`mktemp` - wget -4 -o /dev/null -O $OUTFILE $IPURL - WANIP=`cat $OUTFILE` - rm $OUTFILE - else - #no WAN IP found because of missing check URL - WANIP=${NOIP} - fi - echo $WANIP > $IPFILE + if [ $IPURL ];then + OUTFILE=`mktemp` + wget -4 -o /dev/null -O $OUTFILE $IPURL + WANIP=`cat $OUTFILE` + rm $OUTFILE + else + #no WAN IP found because of missing check URL + WANIP=${NOIP} + fi + echo $WANIP > $IPFILE } cmd=$1 @@ -153,67 +153,67 @@ case $cmd in ;; start) if [ "$(cat $HELPERCFG |grep ^NAT | awk '{print $2}')" = "no" ];then - mv $CFG_disabled $CFG - /etc/init.d/${TOOLNAME} start - else - echo "*/${UPDATEMINUTES} * * * * root $0 update" > $CRONJOB - $0 update - fi + mv $CFG_disabled $CFG + /etc/init.d/${TOOLNAME} start + else + echo "*/${UPDATEMINUTES} * * * * root $0 update" > $CRONJOB + $0 update + fi ;; get-nat) - NAT=`cat $HELPERCFG 2> /dev/null |grep ^NAT | awk '{print $2}'` - [ -z $NAT ] && NAT="unknown" - echo $NAT + NAT=`cat $HELPERCFG 2> /dev/null |grep ^NAT | awk '{print $2}'` + [ -z $NAT ] && NAT="unknown" + echo $NAT + ;; + update) + doReadCFG + OLDIP=`cat $IPFILE` + doGetWANIP + [ -f $CFG_disabled ] && FILE=$CFG_disabled + [ -f $CFG ] && FILE=$CFG + RESULT=0 + #if we know our WAN IP, only update if IP changes + if [ "$OLDIP" != "$WANIP" -a "${WANIP}" != ${NOIP} ];then + ${UPDATE_TOOL} -c $FILE + RESULT=$? + cat /proc/uptime |awk '{print $1}' > $LASTUPDATE + fi + #if we don't know our WAN IP do a blind update once a hour + if [ "${WANIP}" = ${NOIP} ];then + UPTIME=`cat /proc/uptime` + LAST=`cat $LASTUPDATE` + DIFF=`expr $UPTIME - $LAST` + if [ $DIFF -gt $UPDATEMINUTESUNKNOWN ];then + ${UPDATE_TOOL} -c $FILE + RESULT=$? + cat /proc/uptime |awk '{print $1}' > $LASTUPDATE + fi + fi + if [ $RESULT -eq 0 ];then + $0 success + else + $0 failed + fi ;; - update) - doReadCFG - OLDIP=`cat $IPFILE` - doGetWANIP - [ -f $CFG_disabled ] && FILE=$CFG_disabled - [ -f $CFG ] && FILE=$CFG - RESULT=0 - #if we know our WAN IP, only update if IP changes - if [ "$OLDIP" != "$WANIP" -a "${WANIP}" != ${NOIP} ];then - ${UPDATE_TOOL} -c $FILE - RESULT=$? - cat /proc/uptime |awk '{print $1}' > $LASTUPDATE - fi - #if we don't know our WAN IP do a blind update once a hour - if [ "${WANIP}" = ${NOIP} ];then - UPTIME=`cat /proc/uptime` - LAST=`cat $LASTUPDATE` - DIFF=`expr $UPTIME - $LAST` - if [ $DIFF -gt $UPDATEMINUTESUNKNOWN ];then - ${UPDATE_TOOL} -c $FILE - RESULT=$? - cat /proc/uptime |awk '{print $1}' > $LASTUPDATE - fi - fi - if [ $RESULT -eq 0 ];then - $0 success - else - $0 failed - fi - ;; stop) rm $CRONJOB 2> /dev/null /etc/init.d/${TOOLNAME} stop mv $CFG $CFG_disabled ;; success) - DATE=`date` - echo "last update done ($DATE)" > $STATUSFILE + DATE=`date` + echo "last update done ($DATE)" > $STATUSFILE ;; failed) - DATE=`date` - echo "last update failed ($DATE)" > $STATUSFILE + DATE=`date` + echo "last update failed ($DATE)" > $STATUSFILE ;; get-last-success) - if [ -f $STATUSFILE ];then - cat $STATUSFILE - else - echo "no update recorded since last config change" - fi + if [ -f $STATUSFILE ];then + cat $STATUSFILE + else + echo "no update recorded since last config change" + fi ;; get-installed) if [ ! -z ${UPDATE_TOOL} ];then @@ -226,8 +226,8 @@ case $cmd in if [ -f $CRONJOB ];then echo enabled elif [ ! -z $PROC ];then - echo enabled - else + echo enabled + else echo disabled fi echo $server @@ -237,10 +237,10 @@ case $cmd in echo $IPURL ;; get-timer) - echo $UPDATEMINUTES + echo $UPDATEMINUTES ;; clean) - rm ${CFGDIR}/* + rm ${CFGDIR}/* ;; *) echo "usage: get-installed|status|configure |start|stop|update|get-nat|clean|success|failed" @@ -252,10 +252,10 @@ case $cmd in echo "-p Account Password" echo "-I A URL which returns the IP of the client who is requesting" echo "" - echo "update do a one time update" - echo "clean delete configuration" - echo "success store update success" - echo "failed store update failure" + echo "update do a one time update" + echo "clean delete configuration" + echo "success store update success" + echo "failed store update failure" ;; esac exit 0 From eb80d3c68a58162a87306e03cf91f4767160bc43 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Sun, 4 Jan 2015 14:31:41 +0100 Subject: [PATCH 007/103] some args are optional, do not return errors --- actions/dynamicDNS | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/actions/dynamicDNS b/actions/dynamicDNS index fa1fe5a41..79e3cb15c 100755 --- a/actions/dynamicDNS +++ b/actions/dynamicDNS @@ -75,10 +75,6 @@ doGetOpt() echo "Invalid option: -$OPTARG" >&2 exit 1 ;; - :) - echo "Option -$OPTARG requires an argument." >&2 - exit 1 - ;; esac done } @@ -252,10 +248,11 @@ case $cmd in echo "-p Account Password" echo "-I A URL which returns the IP of the client who is requesting" echo "" - echo "update do a one time update" - echo "clean delete configuration" - echo "success store update success" - echo "failed store update failure" + echo "update do a one time update" + echo "clean delete configuration" + echo "success store update success" + echo "failed store update failure" + echo "get-nat return the detected nat type" ;; esac exit 0 From 0f66b22a4af6b1dabaa9a483d140d34716c901fc Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Sun, 4 Jan 2015 18:53:39 +0000 Subject: [PATCH 008/103] refactored naming from dynamicDNS to lowercase dynamicdns --- actions/{dynamicDNS => dynamicdns} | 0 data/etc/plinth/modules-enabled/dynamicDNS | 1 - data/etc/plinth/modules-enabled/dynamicdns | 1 + .../{dynamicDNS => dynamicdns}/__init__.py | 6 +- .../dynamicdns.py} | 120 +++++++++--------- .../templates/dynamicdns.html} | 0 .../templates/dynamicdns_configure.html} | 0 .../templates/dynamicdns_status.html} | 0 .../{dynamicDNS => dynamicdns}/urls.py | 10 +- 9 files changed, 69 insertions(+), 69 deletions(-) rename actions/{dynamicDNS => dynamicdns} (100%) delete mode 100644 data/etc/plinth/modules-enabled/dynamicDNS create mode 100644 data/etc/plinth/modules-enabled/dynamicdns rename plinth/modules/{dynamicDNS => dynamicdns}/__init__.py (90%) mode change 100644 => 100755 rename plinth/modules/{dynamicDNS/dynamicDNS.py => dynamicdns/dynamicdns.py} (68%) mode change 100644 => 100755 rename plinth/modules/{dynamicDNS/templates/dynamicDNS.html => dynamicdns/templates/dynamicdns.html} (100%) mode change 100644 => 100755 rename plinth/modules/{dynamicDNS/templates/dynamicDNS_configure.html => dynamicdns/templates/dynamicdns_configure.html} (100%) mode change 100644 => 100755 rename plinth/modules/{dynamicDNS/templates/dynamicDNS_status.html => dynamicdns/templates/dynamicdns_status.html} (100%) mode change 100644 => 100755 rename plinth/modules/{dynamicDNS => dynamicdns}/urls.py (75%) mode change 100644 => 100755 diff --git a/actions/dynamicDNS b/actions/dynamicdns similarity index 100% rename from actions/dynamicDNS rename to actions/dynamicdns diff --git a/data/etc/plinth/modules-enabled/dynamicDNS b/data/etc/plinth/modules-enabled/dynamicDNS deleted file mode 100644 index aaea9c4e7..000000000 --- a/data/etc/plinth/modules-enabled/dynamicDNS +++ /dev/null @@ -1 +0,0 @@ -plinth.modules.dynamicDNS diff --git a/data/etc/plinth/modules-enabled/dynamicdns b/data/etc/plinth/modules-enabled/dynamicdns new file mode 100644 index 000000000..af54a38dd --- /dev/null +++ b/data/etc/plinth/modules-enabled/dynamicdns @@ -0,0 +1 @@ +plinth.modules.dynamicdns diff --git a/plinth/modules/dynamicDNS/__init__.py b/plinth/modules/dynamicdns/__init__.py old mode 100644 new mode 100755 similarity index 90% rename from plinth/modules/dynamicDNS/__init__.py rename to plinth/modules/dynamicdns/__init__.py index c2b6cabec..0f85c3590 --- a/plinth/modules/dynamicDNS/__init__.py +++ b/plinth/modules/dynamicdns/__init__.py @@ -19,9 +19,9 @@ Plinth module to configure ez-ipupdate client """ -from . import dynamicDNS -from .dynamicDNS import init +from . import dynamicdns +from .dynamicdns import init -__all__ = ['dynamicDNS', 'init'] +__all__ = ['dynamicdns', 'init'] depends = ['plinth.modules.apps'] diff --git a/plinth/modules/dynamicDNS/dynamicDNS.py b/plinth/modules/dynamicdns/dynamicdns.py old mode 100644 new mode 100755 similarity index 68% rename from plinth/modules/dynamicDNS/dynamicDNS.py rename to plinth/modules/dynamicdns/dynamicdns.py index 2a1f03780..15d60f95a --- a/plinth/modules/dynamicDNS/dynamicDNS.py +++ b/plinth/modules/dynamicdns/dynamicdns.py @@ -29,26 +29,26 @@ from plinth import cfg LOGGER = logging.getLogger(__name__) -subsubmenu = [{'url': reverse_lazy('dynamicDNS:index'), +subsubmenu = [{'url': reverse_lazy('dynamicdns:index'), 'text': _('About')}, - {'url': reverse_lazy('dynamicDNS:configure'), + {'url': reverse_lazy('dynamicdns:configure'), 'text': _('Configure')}, - {'url': reverse_lazy('dynamicDNS:statuspage'), + {'url': reverse_lazy('dynamicdns:statuspage'), 'text': _('Status')} ] def init(): - """Initialize the dynamicDNS module""" + """Initialize the dynamicdns module""" menu = cfg.main_menu.get('apps:index') - menu.add_urlname('dynamicDNS', 'glyphicon-comment', 'dynamicDNS:index', 40) + menu.add_urlname('dynamicdns', 'glyphicon-comment', 'dynamicdns:index', 40) @login_required def index(request): """Serve dynamic DNS page""" - is_installed = actions.run('dynamicDNS', ['get-installed']).strip() \ + is_installed = actions.run('dynamicdns', ['get-installed']).strip() \ == 'installed' if is_installed: @@ -56,8 +56,8 @@ def index(request): else: index_subsubmenu = None - return TemplateResponse(request, 'dynamicDNS.html', - {'title': _('dynamicDNS'), + return TemplateResponse(request, 'dynamicdns.html', + {'title': _('dynamicdns'), 'is_installed': is_installed, 'subsubmenu': index_subsubmenu}) @@ -74,42 +74,42 @@ class TrimmedCharField(forms.CharField): class ConfigureForm(forms.Form): """Form to configure the dynamic DNS client""" - enabled = forms.BooleanField(label=_('Enable dynamicDNS'), + enabled = forms.BooleanField(label=_('Enable dynamicdns'), required=False) - dynamicDNS_Server = TrimmedCharField( + dynamicdns_server = TrimmedCharField( label=_('Server Address'), help_text=_('Example: gnudip.provider.org'), validators=[ validators.RegexValidator(r'^[\w-]{1,63}(\.[\w-]{1,63})*$', _('Invalid server name'))]) - dynamicDNS_Domain = TrimmedCharField( + dynamicdns_domain = TrimmedCharField( label=_('Domain Name'), help_text=_('Example: hostname.sds-ip.de'), validators=[ validators.RegexValidator(r'^[\w-]{1,63}(\.[\w-]{1,63})*$', _('Invalid domain name'))]) - dynamicDNS_User = TrimmedCharField( + dynamicdns_user = TrimmedCharField( label=_('Username'), help_text=_('You should have been requested to select a username \ when you created the account')) - dynamicDNS_Secret = TrimmedCharField( + dynamicdns_secret = TrimmedCharField( label=_('Password'), widget=forms.PasswordInput(), required=False, help_text=_('You should have been requested to select a password \ when you created the account. If you left this field \ empty your password will be unchanged.')) - dynamicDNS_Secret_repeat = TrimmedCharField( + dynamicdns_secret_repeat = TrimmedCharField( label=_('repeat Password'), widget=forms.PasswordInput(), required=False, help_text=_('insert the password twice to avoid typos. If you left \ this field empty your password will be unchanged.'),) - dynamicDNS_IPURL = TrimmedCharField( + dynamicdns_ipurl = TrimmedCharField( label=_('IP check URL'), required=False, help_text=_('Optional Value. If your FreedomBox is not connected \ @@ -129,16 +129,16 @@ def configure(request): form = None if request.method == 'POST': - form = ConfigureForm(request.POST, prefix='dynamicDNS') + form = ConfigureForm(request.POST, prefix='dynamicdns') if form.is_valid(): _apply_changes(request, status, form.cleaned_data) status = get_status() - form = ConfigureForm(initial=status, prefix='dynamicDNS') + form = ConfigureForm(initial=status, prefix='dynamicdns') else: - form = ConfigureForm(initial=status, prefix='dynamicDNS') + form = ConfigureForm(initial=status, prefix='dynamicdns') - return TemplateResponse(request, 'dynamicDNS_configure.html', - {'title': _('Configure dynamicDNS Client'), + return TemplateResponse(request, 'dynamicdns_configure.html', + {'title': _('Configure dynamicdns Client'), 'form': form, 'subsubmenu': subsubmenu}) @@ -146,12 +146,12 @@ def configure(request): @login_required def statuspage(request): """Serve the status page """ - check_nat = actions.run('dynamicDNS', ['get-nat']) - last_update = actions.run('dynamicDNS', ['get-last-success']) + check_nat = actions.run('dynamicdns', ['get-nat']) + last_update = actions.run('dynamicdns', ['get-last-success']) no_nat = check_nat.strip() == 'no' nat_unchecked = check_nat.strip() == 'unknown' - timer = actions.run('dynamicDNS', ['get-timer']) + timer = actions.run('dynamicdns', ['get-timer']) if no_nat: LOGGER.info('we are not behind a NAT') @@ -159,8 +159,8 @@ def statuspage(request): if nat_unchecked: LOGGER.info('we did not checked if we are behind a NAT') - return TemplateResponse(request, 'dynamicDNS_status.html', - {'title': _('Status of dynamicDNS Client'), + return TemplateResponse(request, 'dynamicdns_status.html', + {'title': _('Status of dynamicdns Client'), 'no_nat': no_nat, 'nat_unchecked': nat_unchecked, 'timer': timer, @@ -172,33 +172,33 @@ def get_status(): """Return the current status""" """ToDo: use key/value instead of hard coded value list""" status = {} - output = actions.run('dynamicDNS', 'status') + output = actions.run('dynamicdns', 'status') details = output.split() status['enabled'] = (output.split()[0] == 'enabled') if len(details) > 1: - status['dynamicDNS_Server'] = details[1] + status['dynamicdns_server'] = details[1] else: - status['dynamicDNS_Server'] = '' + status['dynamicdns_server'] = '' if len(details) > 2: - status['dynamicDNS_Domain'] = details[2] + status['dynamicdns_domain'] = details[2] else: - status['dynamicDNS_Domain'] = '' + status['dynamicdns_domain'] = '' if len(details) > 3: - status['dynamicDNS_User'] = details[3] + status['dynamicdns_user'] = details[3] else: - status['dynamicDNS_User'] = '' + status['dynamicdns_user'] = '' if len(details) > 4: - status['dynamicDNS_Secret'] = details[4] + status['dynamicdns_secret'] = details[4] else: - status['dynamicDNS_Secret'] = '' + status['dynamicdns_secret'] = '' if len(details) > 5: - status['dynamicDNS_IPURL'] = details[5] + status['dynamicdns_ipurl'] = details[5] else: - status['dynamicDNS_Secret'] = '' + status['dynamicdns_secret'] = '' return status @@ -209,40 +209,40 @@ def _apply_changes(request, old_status, new_status): LOGGER.info('Old status was - %s', old_status) fail = False - if new_status['dynamicDNS_Secret_repeat'] != \ - new_status['dynamicDNS_Secret']: + if new_status['dynamicdns_secret_repeat'] != \ + new_status['dynamicdns_secret']: messages.error(request, _('passwords does not match')) fail = True - if old_status['dynamicDNS_Secret'] == '' and \ - new_status['dynamicDNS_Secret'] == '': + if old_status['dynamicdns_secret'] == '' and \ + new_status['dynamicdns_secret'] == '': messages.error(request, _('please give a password')) fail = True if False == fail: - if new_status['dynamicDNS_Secret'] == '': - new_status['dynamicDNS_Secret'] = old_status['dynamicDNS_Secret'] + if new_status['dynamicdns_secret'] == '': + new_status['dynamicdns_secret'] = old_status['dynamicdns_secret'] - if new_status['dynamicDNS_IPURL'] == '': - new_status['dynamicDNS_IPURL'] = 'none' + if new_status['dynamicdns_ipurl'] == '': + new_status['dynamicdns_ipurl'] = 'none' - if old_status['dynamicDNS_Server'] != \ - new_status['dynamicDNS_Server'] or \ - old_status['dynamicDNS_Domain'] != \ - new_status['dynamicDNS_Domain'] or \ - old_status['dynamicDNS_User'] != \ - new_status['dynamicDNS_User'] or \ - old_status['dynamicDNS_Secret'] != \ - new_status['dynamicDNS_Secret'] or \ - old_status['dynamicDNS_IPURL'] != \ - new_status['dynamicDNS_IPURL']: + if old_status['dynamicdns_server'] != \ + new_status['dynamicdns_server'] or \ + old_status['dynamicdns_domain'] != \ + new_status['dynamicdns_domain'] or \ + old_status['dynamicdns_user'] != \ + new_status['dynamicdns_user'] or \ + old_status['dynamicdns_secret'] != \ + new_status['dynamicdns_secret'] or \ + old_status['dynamicdns_ipurl'] != \ + new_status['dynamicdns_ipurl']: - _run(['configure', '-s', new_status['dynamicDNS_Server'], - '-d', new_status['dynamicDNS_Domain'], - '-u', new_status['dynamicDNS_User'], - '-p', new_status['dynamicDNS_Secret'], - '-I', new_status['dynamicDNS_IPURL']]) + _run(['configure', '-s', new_status['dynamicdns_server'], + '-d', new_status['dynamicdns_domain'], + '-u', new_status['dynamicdns_user'], + '-p', new_status['dynamicdns_secret'], + '-I', new_status['dynamicdns_ipurl']]) _run(['stop']) _run(['start']) messages.success(request, \ @@ -262,7 +262,7 @@ def _apply_changes(request, old_status, new_status): def _run(arguments, superuser=False): """Run a given command and raise exception if there was an error""" - command = 'dynamicDNS' + command = 'dynamicdns' if superuser: return actions.superuser_run(command, arguments) diff --git a/plinth/modules/dynamicDNS/templates/dynamicDNS.html b/plinth/modules/dynamicdns/templates/dynamicdns.html old mode 100644 new mode 100755 similarity index 100% rename from plinth/modules/dynamicDNS/templates/dynamicDNS.html rename to plinth/modules/dynamicdns/templates/dynamicdns.html diff --git a/plinth/modules/dynamicDNS/templates/dynamicDNS_configure.html b/plinth/modules/dynamicdns/templates/dynamicdns_configure.html old mode 100644 new mode 100755 similarity index 100% rename from plinth/modules/dynamicDNS/templates/dynamicDNS_configure.html rename to plinth/modules/dynamicdns/templates/dynamicdns_configure.html diff --git a/plinth/modules/dynamicDNS/templates/dynamicDNS_status.html b/plinth/modules/dynamicdns/templates/dynamicdns_status.html old mode 100644 new mode 100755 similarity index 100% rename from plinth/modules/dynamicDNS/templates/dynamicDNS_status.html rename to plinth/modules/dynamicdns/templates/dynamicdns_status.html diff --git a/plinth/modules/dynamicDNS/urls.py b/plinth/modules/dynamicdns/urls.py old mode 100644 new mode 100755 similarity index 75% rename from plinth/modules/dynamicDNS/urls.py rename to plinth/modules/dynamicdns/urls.py index 61bab8ce2..04ff51485 --- a/plinth/modules/dynamicDNS/urls.py +++ b/plinth/modules/dynamicdns/urls.py @@ -16,15 +16,15 @@ # """ -URLs for the DynamicDNS module +URLs for the dynamicdns module """ from django.conf.urls import patterns, url urlpatterns = patterns( - 'plinth.modules.dynamicDNS.dynamicDNS', - url(r'^apps/dynamicDNS/$', 'index', name='index'), - url(r'^apps/dynamicDNS/configure/$', 'configure', name='configure'), - url(r'^apps/dynamicDNS/statuspage/$', 'statuspage', name='statuspage') + 'plinth.modules.dynamicdns.dynamicdns', + url(r'^apps/dynamicdns/$', 'index', name='index'), + url(r'^apps/dynamicdns/configure/$', 'configure', name='configure'), + url(r'^apps/dynamicdns/statuspage/$', 'statuspage', name='statuspage') ) From a6de17f4d951bd4f48b636787870d2f2f43433ae Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Sun, 4 Jan 2015 19:57:14 +0100 Subject: [PATCH 009/103] fixed file permissions --- plinth/modules/dynamicdns/templates/dynamicdns.html | 0 plinth/modules/dynamicdns/templates/dynamicdns_configure.html | 0 plinth/modules/dynamicdns/templates/dynamicdns_status.html | 0 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 plinth/modules/dynamicdns/templates/dynamicdns.html mode change 100755 => 100644 plinth/modules/dynamicdns/templates/dynamicdns_configure.html mode change 100755 => 100644 plinth/modules/dynamicdns/templates/dynamicdns_status.html diff --git a/plinth/modules/dynamicdns/templates/dynamicdns.html b/plinth/modules/dynamicdns/templates/dynamicdns.html old mode 100755 new mode 100644 diff --git a/plinth/modules/dynamicdns/templates/dynamicdns_configure.html b/plinth/modules/dynamicdns/templates/dynamicdns_configure.html old mode 100755 new mode 100644 diff --git a/plinth/modules/dynamicdns/templates/dynamicdns_status.html b/plinth/modules/dynamicdns/templates/dynamicdns_status.html old mode 100755 new mode 100644 From 69bb4f1b36f3e7e74a6e36accf608b03ec8331c4 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Sun, 4 Jan 2015 19:58:07 +0100 Subject: [PATCH 010/103] fixed file permissions --- plinth/modules/dynamicdns/__init__.py | 0 plinth/modules/dynamicdns/dynamicdns.py | 0 plinth/modules/dynamicdns/urls.py | 0 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 plinth/modules/dynamicdns/__init__.py mode change 100755 => 100644 plinth/modules/dynamicdns/dynamicdns.py mode change 100755 => 100644 plinth/modules/dynamicdns/urls.py diff --git a/plinth/modules/dynamicdns/__init__.py b/plinth/modules/dynamicdns/__init__.py old mode 100755 new mode 100644 diff --git a/plinth/modules/dynamicdns/dynamicdns.py b/plinth/modules/dynamicdns/dynamicdns.py old mode 100755 new mode 100644 diff --git a/plinth/modules/dynamicdns/urls.py b/plinth/modules/dynamicdns/urls.py old mode 100755 new mode 100644 From 08b0f375273811ac00dcf399c31fc39b5ae773f0 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Sun, 4 Jan 2015 20:00:05 +0100 Subject: [PATCH 011/103] fixed pep8 issue --- plinth/modules/dynamicdns/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plinth/modules/dynamicdns/__init__.py b/plinth/modules/dynamicdns/__init__.py index 0f85c3590..747482e9d 100644 --- a/plinth/modules/dynamicdns/__init__.py +++ b/plinth/modules/dynamicdns/__init__.py @@ -16,7 +16,7 @@ # """ -Plinth module to configure ez-ipupdate client +Plinth module to configure ez-ipupdate client """ from . import dynamicdns From 7cb98f2122f4a2a841419ccb2a784c7b5578775e Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Sun, 4 Jan 2015 22:04:40 +0100 Subject: [PATCH 012/103] added install command to action script --- actions/dynamicdns | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/actions/dynamicdns b/actions/dynamicdns index 79e3cb15c..5192a619e 100755 --- a/actions/dynamicdns +++ b/actions/dynamicdns @@ -211,6 +211,18 @@ case $cmd in echo "no update recorded since last config change" fi ;; + install) + cd /tmp/ && apt-get download ${TOOLNAME} + dpkg --unpack ${TOOLNAME}*.deb + rm /var/lib/dpkg/info/${TOOLNAME}.postinst + dpkg --configure ${TOOLNAME} + apt-get install -yf + rm ${TOOLNAME}*.deb + cd - + ;; + uninstall) + apt-get -y remove --purge ez-ipupdate + ;; get-installed) if [ ! -z ${UPDATE_TOOL} ];then echo "installed" From 69c043fefbe50fb5220274b986197080c7230a64 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Sun, 4 Jan 2015 23:16:46 +0100 Subject: [PATCH 013/103] fixed reading uptime from system --- actions/dynamicdns | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/actions/dynamicdns b/actions/dynamicdns index 5192a619e..869691adb 100755 --- a/actions/dynamicdns +++ b/actions/dynamicdns @@ -172,17 +172,18 @@ case $cmd in if [ "$OLDIP" != "$WANIP" -a "${WANIP}" != ${NOIP} ];then ${UPDATE_TOOL} -c $FILE RESULT=$? - cat /proc/uptime |awk '{print $1}' > $LASTUPDATE + cat /proc/uptime |awk '{print $1}' |cut -d . -f 1 > $LASTUPDATE fi #if we don't know our WAN IP do a blind update once a hour if [ "${WANIP}" = ${NOIP} ];then - UPTIME=`cat /proc/uptime` - LAST=`cat $LASTUPDATE` + UPTIME=`cat /proc/uptime |cut -d . -f 1` + LAST=0 + [ -f $LASTUPDATE ] && LAST=`cat $LASTUPDATE` DIFF=`expr $UPTIME - $LAST` if [ $DIFF -gt $UPDATEMINUTESUNKNOWN ];then ${UPDATE_TOOL} -c $FILE RESULT=$? - cat /proc/uptime |awk '{print $1}' > $LASTUPDATE + cat /proc/uptime |awk '{print $1}' |cut -d . -f 1> $LASTUPDATE fi fi if [ $RESULT -eq 0 ];then From a2ffb64996323cbac94e0969f64386471be49e86 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Sun, 4 Jan 2015 22:24:32 +0000 Subject: [PATCH 014/103] fixed status update if nothing was done --- actions/dynamicdns | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/actions/dynamicdns b/actions/dynamicdns index 869691adb..afeca606a 100755 --- a/actions/dynamicdns +++ b/actions/dynamicdns @@ -172,6 +172,7 @@ case $cmd in if [ "$OLDIP" != "$WANIP" -a "${WANIP}" != ${NOIP} ];then ${UPDATE_TOOL} -c $FILE RESULT=$? + [ $RESULT -eq 0 ] && $0 success cat /proc/uptime |awk '{print $1}' |cut -d . -f 1 > $LASTUPDATE fi #if we don't know our WAN IP do a blind update once a hour @@ -183,12 +184,11 @@ case $cmd in if [ $DIFF -gt $UPDATEMINUTESUNKNOWN ];then ${UPDATE_TOOL} -c $FILE RESULT=$? + [ $RESULT -eq 0 ] && $0 success cat /proc/uptime |awk '{print $1}' |cut -d . -f 1> $LASTUPDATE fi fi - if [ $RESULT -eq 0 ];then - $0 success - else + if [ $RESULT -ne 0 ];then $0 failed fi ;; From 4306e4c7708a026a4f131d0ec6b17e0c531c2480 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 5 Jan 2015 00:29:03 +0100 Subject: [PATCH 015/103] changed menu entry name to a more fancy string --- plinth/modules/dynamicdns/dynamicdns.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plinth/modules/dynamicdns/dynamicdns.py b/plinth/modules/dynamicdns/dynamicdns.py index 15d60f95a..6dd8c6a09 100644 --- a/plinth/modules/dynamicdns/dynamicdns.py +++ b/plinth/modules/dynamicdns/dynamicdns.py @@ -41,7 +41,7 @@ subsubmenu = [{'url': reverse_lazy('dynamicdns:index'), def init(): """Initialize the dynamicdns module""" menu = cfg.main_menu.get('apps:index') - menu.add_urlname('dynamicdns', 'glyphicon-comment', 'dynamicdns:index', 40) + menu.add_urlname('Dynamic DNS', 'glyphicon-comment', 'dynamicdns:index', 40) @login_required From 4978c64bb36338863b0f3021fbe5da59f9fef19a Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 5 Jan 2015 11:22:07 +0000 Subject: [PATCH 016/103] use package framework for installing ez-ipupdate --- plinth/modules/dynamicdns/dynamicdns.py | 13 +++++-------- .../modules/dynamicdns/templates/dynamicdns.html | 16 +--------------- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/plinth/modules/dynamicdns/dynamicdns.py b/plinth/modules/dynamicdns/dynamicdns.py index 15d60f95a..a3c80746c 100644 --- a/plinth/modules/dynamicdns/dynamicdns.py +++ b/plinth/modules/dynamicdns/dynamicdns.py @@ -26,6 +26,7 @@ import logging from plinth import actions from plinth import cfg +from plinth import package LOGGER = logging.getLogger(__name__) @@ -45,20 +46,14 @@ def init(): @login_required +@package.required('ez-ipupdate') def index(request): """Serve dynamic DNS page""" - is_installed = actions.run('dynamicdns', ['get-installed']).strip() \ - == 'installed' - - if is_installed: - index_subsubmenu = subsubmenu - else: - index_subsubmenu = None + index_subsubmenu = subsubmenu return TemplateResponse(request, 'dynamicdns.html', {'title': _('dynamicdns'), - 'is_installed': is_installed, 'subsubmenu': index_subsubmenu}) @@ -123,6 +118,7 @@ class ConfigureForm(forms.Form): @login_required +@package.required('ez-ipupdate') def configure(request): """Serve the configuration form""" status = get_status() @@ -144,6 +140,7 @@ def configure(request): @login_required +@package.required('ez-ipupdate') def statuspage(request): """Serve the status page """ check_nat = actions.run('dynamicdns', ['get-nat']) diff --git a/plinth/modules/dynamicdns/templates/dynamicdns.html b/plinth/modules/dynamicdns/templates/dynamicdns.html index 44607d12d..cf6afdb93 100644 --- a/plinth/modules/dynamicdns/templates/dynamicdns.html +++ b/plinth/modules/dynamicdns/templates/dynamicdns.html @@ -21,22 +21,8 @@ {% load bootstrap %} {% block content %} - -{% if is_installed %} - +

DynamicDNS client

If your internet provider changes your IP address periodic (i.e. every 24h) it may be hard for others to find you in the WEB. And for this reason nobody may find the services which are provided by freedombox (like your owncloud). The solution is to assign a DNS name to your IP address and update the DNS name every time your IP is changed by your Internet provider. Dynamic DNS allows you to push your current public IP address to an gnudip server. Afterwards the Server will assign your personal DNS name with the new IP and if someone from the internet asks for your DNS name he will get your personal IP answered.

-{% else %} - -

DynamicDNS client

- -

The Dynamic DNS tool ez-ipupdate is not installed.

- -

ez-ipupdate comes pre-installed with {{ cfg.box_name }}. On any Debian-based - system (such as {{ cfg.box_name }}) you may install it using the command - apt-get install ez-ipupdate.

- -{% endif %} - {% endblock %} From e91aa7fa447a39c37e4262ce576bebd0a6644872 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 5 Jan 2015 11:33:28 +0000 Subject: [PATCH 017/103] removed obsolete install options because installation process is done by package framework now --- actions/dynamicdns | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/actions/dynamicdns b/actions/dynamicdns index afeca606a..b6123296c 100755 --- a/actions/dynamicdns +++ b/actions/dynamicdns @@ -212,23 +212,6 @@ case $cmd in echo "no update recorded since last config change" fi ;; - install) - cd /tmp/ && apt-get download ${TOOLNAME} - dpkg --unpack ${TOOLNAME}*.deb - rm /var/lib/dpkg/info/${TOOLNAME}.postinst - dpkg --configure ${TOOLNAME} - apt-get install -yf - rm ${TOOLNAME}*.deb - cd - - ;; - uninstall) - apt-get -y remove --purge ez-ipupdate - ;; - get-installed) - if [ ! -z ${UPDATE_TOOL} ];then - echo "installed" - fi - ;; status) doReadCFG PROC=`pgrep ${TOOLNAME}` @@ -252,7 +235,7 @@ case $cmd in rm ${CFGDIR}/* ;; *) - echo "usage: get-installed|status|configure |start|stop|update|get-nat|clean|success|failed" + echo "usage: status|configure |start|stop|update|get-nat|clean|success|failed" echo "" echo "options are:" echo "-s Gnudip Server address" From 920b51d606edaa568c56a9e8f4e880984dddfdc0 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 5 Jan 2015 12:28:17 +0000 Subject: [PATCH 018/103] do not load bootstrap template filters if not needed --- plinth/modules/dynamicdns/templates/dynamicdns.html | 2 -- plinth/modules/dynamicdns/templates/dynamicdns_status.html | 2 -- 2 files changed, 4 deletions(-) diff --git a/plinth/modules/dynamicdns/templates/dynamicdns.html b/plinth/modules/dynamicdns/templates/dynamicdns.html index cf6afdb93..d82a41619 100644 --- a/plinth/modules/dynamicdns/templates/dynamicdns.html +++ b/plinth/modules/dynamicdns/templates/dynamicdns.html @@ -18,8 +18,6 @@ # {% endcomment %} -{% load bootstrap %} - {% block content %}

DynamicDNS client

If your internet provider changes your IP address periodic (i.e. every 24h) it may be hard for others to find you in the WEB. And for this reason nobody may find the services which are provided by freedombox (like your owncloud). The solution is to assign a DNS name to your IP address and update the DNS name every time your IP is changed by your Internet provider. Dynamic DNS allows you to push your current public IP address to an

NAT type

From a26316436c9b8f0fc4669ac26d62babffe7938d3 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 5 Jan 2015 12:34:56 +0000 Subject: [PATCH 019/103] fixed endention --- .../templates/dynamicdns_status.html | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/plinth/modules/dynamicdns/templates/dynamicdns_status.html b/plinth/modules/dynamicdns/templates/dynamicdns_status.html index 466acf3b3..22c8ddec0 100644 --- a/plinth/modules/dynamicdns/templates/dynamicdns_status.html +++ b/plinth/modules/dynamicdns/templates/dynamicdns_status.html @@ -22,16 +22,16 @@

NAT type

{% if nat_unchecked %} - NAT type not detected yet, if you do not provide a "IP check URL" we will - not detect a NAT type. + NAT type not detected yet, if you do not provide a "IP check URL" we will + not detect a NAT type. {% else %} - {% if no_nat %} - Direct connection to the internet. - {% else %} - Behind NAT, this means that dynamic DNS service will poll the - "IP check URL" for changes (we need the "IP check URL" for this reason - otherwise we will not detect IP changes). - It may take up to {{ timer }} minutes until we update your DNS entry in case of WAN IP change. - {% endif %} + {% if no_nat %} + Direct connection to the internet. + {% else %} + Behind NAT, this means that dynamic DNS service will poll the + "IP check URL" for changes (we need the "IP check URL" for this reason - otherwise we will not detect IP changes). + It may take up to {{ timer }} minutes until we update your DNS entry in case of WAN IP change. + {% endif %} {% endif %}

Last update

{{ last_update }} From ae4bdc0970a19710044e13efe158a1106e7cf0cb Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 5 Jan 2015 13:54:13 +0100 Subject: [PATCH 020/103] pep8 guideline adaption --- plinth/modules/dynamicdns/dynamicdns.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plinth/modules/dynamicdns/dynamicdns.py b/plinth/modules/dynamicdns/dynamicdns.py index ea143f1df..62ef994ea 100644 --- a/plinth/modules/dynamicdns/dynamicdns.py +++ b/plinth/modules/dynamicdns/dynamicdns.py @@ -42,7 +42,8 @@ subsubmenu = [{'url': reverse_lazy('dynamicdns:index'), def init(): """Initialize the dynamicdns module""" menu = cfg.main_menu.get('apps:index') - menu.add_urlname('Dynamic DNS', 'glyphicon-comment', 'dynamicdns:index', 40) + menu.add_urlname('Dynamic DNS', 'glyphicon-comment', \ + 'dynamicdns:index', 40) @login_required From c0f4b8205ee020590f5e9e171c29fa79e3a9f3eb Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 5 Jan 2015 16:12:24 +0000 Subject: [PATCH 021/103] fixed pep8 errors reported by flake8 --- plinth/modules/dynamicdns/dynamicdns.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/plinth/modules/dynamicdns/dynamicdns.py b/plinth/modules/dynamicdns/dynamicdns.py index 62ef994ea..3d2b1bc6d 100644 --- a/plinth/modules/dynamicdns/dynamicdns.py +++ b/plinth/modules/dynamicdns/dynamicdns.py @@ -42,8 +42,8 @@ subsubmenu = [{'url': reverse_lazy('dynamicdns:index'), def init(): """Initialize the dynamicdns module""" menu = cfg.main_menu.get('apps:index') - menu.add_urlname('Dynamic DNS', 'glyphicon-comment', \ - 'dynamicdns:index', 40) + menu.add_urlname('Dynamic DNS', 'glyphicon-comment', + 'dynamicdns:index', 40) @login_required @@ -214,7 +214,7 @@ def _apply_changes(request, old_status, new_status): fail = True if old_status['dynamicdns_secret'] == '' and \ - new_status['dynamicdns_secret'] == '': + new_status['dynamicdns_secret'] == '': messages.error(request, _('please give a password')) fail = True @@ -243,8 +243,8 @@ def _apply_changes(request, old_status, new_status): '-I', new_status['dynamicdns_ipurl']]) _run(['stop']) _run(['start']) - messages.success(request, \ - _('Dynamic DNS configuration is updated!')) + messages.success(request, + _('Dynamic DNS configuration is updated!')) if old_status['enabled'] != new_status['enabled']: if new_status['enabled']: @@ -254,8 +254,9 @@ def _apply_changes(request, old_status, new_status): _run(['stop']) messages.success(request, _('Dynamic DNS is disabled now!')) else: - messages.error(request, \ - _('At least on failure occured, please check your input.')) + messages.error(request, + _('At least on failure occured,\ + please check your input.')) def _run(arguments, superuser=False): From cb52d7fcf076f1974bf4ed0f5d1e842d5fd2f4d6 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 5 Jan 2015 16:20:28 +0000 Subject: [PATCH 022/103] do not report errors on first run --- actions/dynamicdns | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/actions/dynamicdns b/actions/dynamicdns index b6123296c..8fb8d1ef4 100755 --- a/actions/dynamicdns +++ b/actions/dynamicdns @@ -90,8 +90,8 @@ doWriteCFG() #reset the last updated IP echo "0.0.0.0" > $IPFILE - #reset last update - rm $STATUSFILE + #reset last update (if there is one) + rm $STATUSFILE 2> /dev/null #find the interface (always the default gateway interface) DEFAULT=`ip route |grep default |awk '{print $5}'` @@ -128,7 +128,7 @@ doWriteCFG() doGetWANIP() { - if [ $IPURL ];then + if [ ! -z $IPURL ];then OUTFILE=`mktemp` wget -4 -o /dev/null -O $OUTFILE $IPURL WANIP=`cat $OUTFILE` From 6b6e7f695fd6ec1d4dcc53f416b09170201a051e Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 5 Jan 2015 17:08:15 +0000 Subject: [PATCH 023/103] improved robustness of update script in case of connection trouble (wget may hang a long time if DNS fails or route is unavailable) --- actions/dynamicdns | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/actions/dynamicdns b/actions/dynamicdns index 8fb8d1ef4..2b403b2d2 100755 --- a/actions/dynamicdns +++ b/actions/dynamicdns @@ -6,6 +6,8 @@ PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin #static values +WGET=$(which wget) +WGETOPTIONS="-4 -o /dev/null -t 3 -T 3" EMPTYSTRING="none" NOIP="0.0.0.0" #how often do we poll for IP changes if we are behind a NAT? @@ -130,7 +132,7 @@ doGetWANIP() { if [ ! -z $IPURL ];then OUTFILE=`mktemp` - wget -4 -o /dev/null -O $OUTFILE $IPURL + $WGET $WGETOPTIONS -O $OUTFILE $IPURL WANIP=`cat $OUTFILE` rm $OUTFILE else From 9fbe9754f631bae7de6a92288e7e74e455f5deba Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 5 Jan 2015 17:29:12 +0000 Subject: [PATCH 024/103] refactored configuration action to avoid multiple start/stop calls of the action script when the configuration changes --- plinth/modules/dynamicdns/dynamicdns.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/plinth/modules/dynamicdns/dynamicdns.py b/plinth/modules/dynamicdns/dynamicdns.py index 3d2b1bc6d..ddf467312 100644 --- a/plinth/modules/dynamicdns/dynamicdns.py +++ b/plinth/modules/dynamicdns/dynamicdns.py @@ -234,25 +234,24 @@ def _apply_changes(request, old_status, new_status): old_status['dynamicdns_secret'] != \ new_status['dynamicdns_secret'] or \ old_status['dynamicdns_ipurl'] != \ - new_status['dynamicdns_ipurl']: + new_status['dynamicdns_ipurl'] or \ + old_status['enabled'] != \ + new_status['enabled']: _run(['configure', '-s', new_status['dynamicdns_server'], '-d', new_status['dynamicdns_domain'], '-u', new_status['dynamicdns_user'], '-p', new_status['dynamicdns_secret'], '-I', new_status['dynamicdns_ipurl']]) - _run(['stop']) - _run(['start']) - messages.success(request, - _('Dynamic DNS configuration is updated!')) - if old_status['enabled'] != new_status['enabled']: + if old_status['enabled']: + _run(['stop']) + if new_status['enabled']: _run(['start']) - messages.success(request, _('Dynamic DNS is enabled now!')) - else: - _run(['stop']) - messages.success(request, _('Dynamic DNS is disabled now!')) + + messages.success(request, + _('Dynamic DNS configuration is updated!')) else: messages.error(request, _('At least on failure occured,\ From 91cc161f9626304f0071ab3bfae3bf377c8d5095 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 5 Jan 2015 20:48:45 +0000 Subject: [PATCH 025/103] fixed indention --- actions/dynamicdns | 50 +++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/actions/dynamicdns b/actions/dynamicdns index 2b403b2d2..607e8c3ed 100755 --- a/actions/dynamicdns +++ b/actions/dynamicdns @@ -164,35 +164,35 @@ case $cmd in echo $NAT ;; update) - doReadCFG - OLDIP=`cat $IPFILE` - doGetWANIP - [ -f $CFG_disabled ] && FILE=$CFG_disabled - [ -f $CFG ] && FILE=$CFG - RESULT=0 - #if we know our WAN IP, only update if IP changes - if [ "$OLDIP" != "$WANIP" -a "${WANIP}" != ${NOIP} ];then - ${UPDATE_TOOL} -c $FILE - RESULT=$? - [ $RESULT -eq 0 ] && $0 success - cat /proc/uptime |awk '{print $1}' |cut -d . -f 1 > $LASTUPDATE - fi - #if we don't know our WAN IP do a blind update once a hour - if [ "${WANIP}" = ${NOIP} ];then - UPTIME=`cat /proc/uptime |cut -d . -f 1` - LAST=0 - [ -f $LASTUPDATE ] && LAST=`cat $LASTUPDATE` - DIFF=`expr $UPTIME - $LAST` - if [ $DIFF -gt $UPDATEMINUTESUNKNOWN ];then + doReadCFG + OLDIP=`cat $IPFILE` + doGetWANIP + [ -f $CFG_disabled ] && FILE=$CFG_disabled + [ -f $CFG ] && FILE=$CFG + RESULT=0 + #if we know our WAN IP, only update if IP changes + if [ "$OLDIP" != "$WANIP" -a "${WANIP}" != ${NOIP} ];then ${UPDATE_TOOL} -c $FILE RESULT=$? [ $RESULT -eq 0 ] && $0 success - cat /proc/uptime |awk '{print $1}' |cut -d . -f 1> $LASTUPDATE + cat /proc/uptime |awk '{print $1}' |cut -d . -f 1 > $LASTUPDATE + fi + #if we don't know our WAN IP do a blind update once a hour + if [ "${WANIP}" = ${NOIP} ];then + UPTIME=`cat /proc/uptime |cut -d . -f 1` + LAST=0 + [ -f $LASTUPDATE ] && LAST=`cat $LASTUPDATE` + DIFF=`expr $UPTIME - $LAST` + if [ $DIFF -gt $UPDATEMINUTESUNKNOWN ];then + ${UPDATE_TOOL} -c $FILE + RESULT=$? + [ $RESULT -eq 0 ] && $0 success + cat /proc/uptime |awk '{print $1}' |cut -d . -f 1> $LASTUPDATE + fi + fi + if [ $RESULT -ne 0 ];then + $0 failed fi - fi - if [ $RESULT -ne 0 ];then - $0 failed - fi ;; stop) rm $CRONJOB 2> /dev/null From d2fdf1d403b71f763af8769bb93e11a757995752 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 5 Jan 2015 21:14:07 +0000 Subject: [PATCH 026/103] fixed an issue where first update after initial configuration will not work because the cronjob does not recognize the ip change --- actions/dynamicdns | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/actions/dynamicdns b/actions/dynamicdns index 607e8c3ed..1d88420b3 100755 --- a/actions/dynamicdns +++ b/actions/dynamicdns @@ -139,7 +139,6 @@ doGetWANIP() #no WAN IP found because of missing check URL WANIP=${NOIP} fi - echo $WANIP > $IPFILE } cmd=$1 @@ -174,7 +173,7 @@ case $cmd in if [ "$OLDIP" != "$WANIP" -a "${WANIP}" != ${NOIP} ];then ${UPDATE_TOOL} -c $FILE RESULT=$? - [ $RESULT -eq 0 ] && $0 success + [ $RESULT -eq 0 ] && $0 success $WANIP cat /proc/uptime |awk '{print $1}' |cut -d . -f 1 > $LASTUPDATE fi #if we don't know our WAN IP do a blind update once a hour @@ -186,7 +185,7 @@ case $cmd in if [ $DIFF -gt $UPDATEMINUTESUNKNOWN ];then ${UPDATE_TOOL} -c $FILE RESULT=$? - [ $RESULT -eq 0 ] && $0 success + [ $RESULT -eq 0 ] && $0 success $WANIP cat /proc/uptime |awk '{print $1}' |cut -d . -f 1> $LASTUPDATE fi fi @@ -202,6 +201,7 @@ case $cmd in success) DATE=`date` echo "last update done ($DATE)" > $STATUSFILE + echo $1 > $IPFILE ;; failed) DATE=`date` @@ -237,7 +237,7 @@ case $cmd in rm ${CFGDIR}/* ;; *) - echo "usage: status|configure |start|stop|update|get-nat|clean|success|failed" + echo "usage: status|configure |start|stop|update|get-nat|clean|success [updated IP]|failed" echo "" echo "options are:" echo "-s Gnudip Server address" @@ -248,7 +248,7 @@ case $cmd in echo "" echo "update do a one time update" echo "clean delete configuration" - echo "success store update success" + echo "success store update success and optional the updated IP" echo "failed store update failure" echo "get-nat return the detected nat type" ;; From 4ca76b9c7621e27fcdcb7d3daa70af60d6c70944 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Thu, 15 Jan 2015 19:33:11 +0000 Subject: [PATCH 027/103] some helptext adjustments --- plinth/modules/dynamicdns/dynamicdns.py | 6 ++---- plinth/modules/dynamicdns/templates/dynamicdns.html | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/plinth/modules/dynamicdns/dynamicdns.py b/plinth/modules/dynamicdns/dynamicdns.py index ddf467312..dc05f5153 100644 --- a/plinth/modules/dynamicdns/dynamicdns.py +++ b/plinth/modules/dynamicdns/dynamicdns.py @@ -96,14 +96,12 @@ class ConfigureForm(forms.Form): label=_('Password'), widget=forms.PasswordInput(), required=False, help_text=_('You should have been requested to select a password \ - when you created the account. If you left this field \ - empty your password will be unchanged.')) + when you created the account.')) dynamicdns_secret_repeat = TrimmedCharField( label=_('repeat Password'), widget=forms.PasswordInput(), required=False, - help_text=_('insert the password twice to avoid typos. If you left \ - this field empty your password will be unchanged.'),) + help_text=_('insert the password again to avoid typos.'),) dynamicdns_ipurl = TrimmedCharField( label=_('IP check URL'), diff --git a/plinth/modules/dynamicdns/templates/dynamicdns.html b/plinth/modules/dynamicdns/templates/dynamicdns.html index d82a41619..aac14de6f 100644 --- a/plinth/modules/dynamicdns/templates/dynamicdns.html +++ b/plinth/modules/dynamicdns/templates/dynamicdns.html @@ -20,7 +20,7 @@ {% block content %}

DynamicDNS client

-

If your internet provider changes your IP address periodic (i.e. every 24h) it may be hard for others to find you in the WEB. And for this reason nobody may find the services which are provided by freedombox (like your owncloud). The solution is to assign a DNS name to your IP address and update the DNS name every time your IP is changed by your Internet provider. Dynamic DNS allows you to push your current public IP address to an gnudip server. Afterwards the Server will assign your personal DNS name with the new IP and if someone from the internet asks for your DNS name he will get your personal IP answered.

+

If your internet provider changes your IP address periodic (i.e. every 24h) it may be hard for others to find you in the WEB. And for this reason nobody may find the services which are provided by FreedomBox (like your ownCloud). The solution is to assign a DNS name to your IP address and update the DNS name every time your IP is changed by your Internet provider. Dynamic DNS allows you to push your current public IP address to an gnudip server. Afterwards the Server will assign your DNS name with the new IP and if someone from the internet asks for your DNS name he will get your current IP answered. If you are looking for a free dynamic DNS account, you may find one here

{% endblock %} From 411abfe95415ec60b3819df0fd058bf6cbef9723 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Thu, 15 Jan 2015 21:30:25 +0000 Subject: [PATCH 028/103] use start-stop-daemon to avoid hanging web page if ez-ipupdate tool is blocking --- actions/dynamicdns | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/actions/dynamicdns b/actions/dynamicdns index 1d88420b3..1491a0f10 100755 --- a/actions/dynamicdns +++ b/actions/dynamicdns @@ -26,6 +26,7 @@ STATUSFILE="${CFGDIR}${TOOLNAME}.status" LASTUPDATE="${CFGDIR}/last-update" HELPERCFG="${CFGDIR}${TOOLNAME}-plinth.cfg" CRONJOB="/etc/cron.d/${TOOLNAME}" +PIDFILE="/var/run/ez-ipupdate.pid" doReadCFG() { @@ -104,7 +105,6 @@ doWriteCFG() echo "user=${user}:${pass}" >> $FILE echo "service-type=gnudip" >> $FILE echo "retrys=5" >> $FILE - echo "execute=$0 success" >> $FILE echo "wildcard" >> $FILE #check if we are behind a NAT Router @@ -124,6 +124,7 @@ doWriteCFG() echo "interface=$DEFAULT" >> $FILE #if this line is added to config file, ez-ipupdate will be launched on startup via init.d echo "daemon" >> $FILE + echo "execute=$0 success" >> $FILE fi fi } @@ -166,42 +167,45 @@ case $cmd in doReadCFG OLDIP=`cat $IPFILE` doGetWANIP + echo $WANIP > $IPFILE [ -f $CFG_disabled ] && FILE=$CFG_disabled [ -f $CFG ] && FILE=$CFG - RESULT=0 + cat $FILE |grep -v execute > ${FILE}.tmp + mv ${FILE}.tmp ${FILE} + echo "execute=$0 success ${WANIP}" >> $FILE #if we know our WAN IP, only update if IP changes - if [ "$OLDIP" != "$WANIP" -a "${WANIP}" != ${NOIP} ];then - ${UPDATE_TOOL} -c $FILE - RESULT=$? - [ $RESULT -eq 0 ] && $0 success $WANIP - cat /proc/uptime |awk '{print $1}' |cut -d . -f 1 > $LASTUPDATE + if [ "${OLDIP}" != "${WANIP}" -a "${WANIP}" != ${NOIP} ];then + start-stop-daemon -S -x ${UPDATE_TOOL} -m -p ${PIDFILE} -- -c $FILE fi #if we don't know our WAN IP do a blind update once a hour if [ "${WANIP}" = ${NOIP} ];then UPTIME=`cat /proc/uptime |cut -d . -f 1` LAST=0 - [ -f $LASTUPDATE ] && LAST=`cat $LASTUPDATE` + [ -f ${LASTUPDATE} ] && LAST=`cat $LASTUPDATE` DIFF=`expr $UPTIME - $LAST` if [ $DIFF -gt $UPDATEMINUTESUNKNOWN ];then - ${UPDATE_TOOL} -c $FILE - RESULT=$? - [ $RESULT -eq 0 ] && $0 success $WANIP - cat /proc/uptime |awk '{print $1}' |cut -d . -f 1> $LASTUPDATE + start-stop-daemon -S -x ${UPDATE_TOOL} -m -p ${PIDFILE} -- -c $FILE fi fi - if [ $RESULT -ne 0 ];then - $0 failed - fi ;; stop) rm $CRONJOB 2> /dev/null /etc/init.d/${TOOLNAME} stop + kill $(cat ${PIDFILE}) 2> /dev/null mv $CFG $CFG_disabled ;; success) DATE=`date` echo "last update done ($DATE)" > $STATUSFILE - echo $1 > $IPFILE + cat /proc/uptime |awk '{print $1}' |cut -d . -f 1 > $LASTUPDATE + #if called from cronjob, the current IP is given as parameter + if [ $# -eq 1 ];then + echo $1 > $IPFILE + else + #if called from ez-ipupdate daemon, no WAN IP is given as parameter + doGetWANIP + echo $WANIP > $IPFILE + fi ;; failed) DATE=`date` @@ -211,7 +215,7 @@ case $cmd in if [ -f $STATUSFILE ];then cat $STATUSFILE else - echo "no update recorded since last config change" + echo "no successful update recorded since last config change" fi ;; status) From 81c405cfa399a4f60a404a122c857fe93006dbf3 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 23 Feb 2015 12:23:18 +0000 Subject: [PATCH 029/103] fixed typo within error message --- plinth/modules/dynamicdns/dynamicdns.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plinth/modules/dynamicdns/dynamicdns.py b/plinth/modules/dynamicdns/dynamicdns.py index dc05f5153..69157f372 100644 --- a/plinth/modules/dynamicdns/dynamicdns.py +++ b/plinth/modules/dynamicdns/dynamicdns.py @@ -252,7 +252,7 @@ def _apply_changes(request, old_status, new_status): _('Dynamic DNS configuration is updated!')) else: messages.error(request, - _('At least on failure occured,\ + _('At least one failure occured,\ please check your input.')) From 88358de59e491140f4e5d8320956ba6eb91796f4 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 23 Feb 2015 12:30:47 +0000 Subject: [PATCH 030/103] made html templates more readable --- .../modules/dynamicdns/templates/dynamicdns.html | 16 +++++++++++++--- .../dynamicdns/templates/dynamicdns_status.html | 6 ++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/plinth/modules/dynamicdns/templates/dynamicdns.html b/plinth/modules/dynamicdns/templates/dynamicdns.html index aac14de6f..2fedddc15 100644 --- a/plinth/modules/dynamicdns/templates/dynamicdns.html +++ b/plinth/modules/dynamicdns/templates/dynamicdns.html @@ -20,7 +20,17 @@ {% block content %}

DynamicDNS client

-

If your internet provider changes your IP address periodic (i.e. every 24h) it may be hard for others to find you in the WEB. And for this reason nobody may find the services which are provided by FreedomBox (like your ownCloud). The solution is to assign a DNS name to your IP address and update the DNS name every time your IP is changed by your Internet provider. Dynamic DNS allows you to push your current public IP address to an gnudip server. Afterwards the Server will assign your DNS name with the new IP and if someone from the internet asks for your DNS name he will get your current IP answered. If you are looking for a free dynamic DNS account, you may find one here

- +

If your internet provider changes your IP address periodic (i.e. every 24h) + it may be hard for others to find you in the WEB. And for this reason nobody + may find the services which are provided by FreedomBox (like your ownCloud). +

+ The solution is to assign a DNS name to your IP address and update the DNS + name every time your IP is changed by your Internet provider. Dynamic DNS + allows you to push your current public IP address to an + gnudip server. + Afterwards the Server will assign your DNS name with the new IP and if someone + from the internet asks for your DNS name he will get your current IP answered. +

+ If you are looking for a free dynamic DNS account, you may find one + here {% endblock %} diff --git a/plinth/modules/dynamicdns/templates/dynamicdns_status.html b/plinth/modules/dynamicdns/templates/dynamicdns_status.html index 22c8ddec0..dad90326a 100644 --- a/plinth/modules/dynamicdns/templates/dynamicdns_status.html +++ b/plinth/modules/dynamicdns/templates/dynamicdns_status.html @@ -29,8 +29,10 @@ Direct connection to the internet. {% else %} Behind NAT, this means that dynamic DNS service will poll the - "IP check URL" for changes (we need the "IP check URL" for this reason - otherwise we will not detect IP changes). - It may take up to {{ timer }} minutes until we update your DNS entry in case of WAN IP change. + "IP check URL" for changes (we need the "IP check URL" for this reason + - otherwise we will not detect IP changes). + It may take up to {{ timer }} minutes until we update your DNS entry in + case of WAN IP change. {% endif %} {% endif %}

Last update

From c0587fd9df320247b63798d53139909135d2664c Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 23 Feb 2015 12:41:28 +0000 Subject: [PATCH 031/103] reduce retry conuter to avoid UI blocking time --- actions/dynamicdns | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/dynamicdns b/actions/dynamicdns index 1491a0f10..a097b0146 100755 --- a/actions/dynamicdns +++ b/actions/dynamicdns @@ -104,7 +104,7 @@ doWriteCFG() echo "server=$server" >> $FILE echo "user=${user}:${pass}" >> $FILE echo "service-type=gnudip" >> $FILE - echo "retrys=5" >> $FILE + echo "retrys=3" >> $FILE echo "wildcard" >> $FILE #check if we are behind a NAT Router From 17ffdd6feed1da80b30d2c90b982070b4f2549b3 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 23 Feb 2015 12:42:10 +0000 Subject: [PATCH 032/103] made code more readable --- plinth/modules/dynamicdns/dynamicdns.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plinth/modules/dynamicdns/dynamicdns.py b/plinth/modules/dynamicdns/dynamicdns.py index 69157f372..131a690ed 100644 --- a/plinth/modules/dynamicdns/dynamicdns.py +++ b/plinth/modules/dynamicdns/dynamicdns.py @@ -216,7 +216,7 @@ def _apply_changes(request, old_status, new_status): messages.error(request, _('please give a password')) fail = True - if False == fail: + if not fail: if new_status['dynamicdns_secret'] == '': new_status['dynamicdns_secret'] = old_status['dynamicdns_secret'] From 7ea9e1cf949f66b2bae0cbb0767867f4ec11cf53 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 23 Feb 2015 12:51:41 +0000 Subject: [PATCH 033/103] use different UI logo than XMPP --- plinth/modules/dynamicdns/dynamicdns.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plinth/modules/dynamicdns/dynamicdns.py b/plinth/modules/dynamicdns/dynamicdns.py index 131a690ed..3f2c34fc7 100644 --- a/plinth/modules/dynamicdns/dynamicdns.py +++ b/plinth/modules/dynamicdns/dynamicdns.py @@ -42,7 +42,7 @@ subsubmenu = [{'url': reverse_lazy('dynamicdns:index'), def init(): """Initialize the dynamicdns module""" menu = cfg.main_menu.get('apps:index') - menu.add_urlname('Dynamic DNS', 'glyphicon-comment', + menu.add_urlname('Dynamic DNS', 'glyphicon-refresh', 'dynamicdns:index', 40) From 2dbdc0c685ed6ed8c5dde1e107c1f788ac7c3037 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 23 Feb 2015 13:38:58 +0000 Subject: [PATCH 034/103] do form validation within clean function of the ConfigureForm class and not when applying the changes --- plinth/modules/dynamicdns/dynamicdns.py | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/plinth/modules/dynamicdns/dynamicdns.py b/plinth/modules/dynamicdns/dynamicdns.py index 3f2c34fc7..8d0d05c90 100644 --- a/plinth/modules/dynamicdns/dynamicdns.py +++ b/plinth/modules/dynamicdns/dynamicdns.py @@ -115,6 +115,15 @@ class ConfigureForm(forms.Form): validators=[ validators.URLValidator(schemes=['http', 'https', 'ftp'])]) + def clean(self): + cleaned_data = super(ConfigureForm, self).clean() + dynamicdns_secret = cleaned_data.get("dynamicdns_secret") + dynamicdns_secret_repeat = cleaned_data.get("dynamicdns_secret_repeat") + + if dynamicdns_secret or dynamicdns_secret_repeat: + if dynamicdns_secret != dynamicdns_secret_repeat: + raise forms.ValidationError("password missmatch") + @login_required @package.required('ez-ipupdate') @@ -203,20 +212,11 @@ def _apply_changes(request, old_status, new_status): """Apply the changes to Dynamic DNS client""" LOGGER.info('New status is - %s', new_status) LOGGER.info('Old status was - %s', old_status) - fail = False - - if new_status['dynamicdns_secret_repeat'] != \ - new_status['dynamicdns_secret']: - - messages.error(request, _('passwords does not match')) - fail = True if old_status['dynamicdns_secret'] == '' and \ new_status['dynamicdns_secret'] == '': messages.error(request, _('please give a password')) - fail = True - - if not fail: + else: if new_status['dynamicdns_secret'] == '': new_status['dynamicdns_secret'] = old_status['dynamicdns_secret'] @@ -244,16 +244,11 @@ def _apply_changes(request, old_status, new_status): if old_status['enabled']: _run(['stop']) - if new_status['enabled']: _run(['start']) messages.success(request, _('Dynamic DNS configuration is updated!')) - else: - messages.error(request, - _('At least one failure occured,\ - please check your input.')) def _run(arguments, superuser=False): From fa3b5ae9e67c509054cbf929396b21c21cc51937 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 23 Feb 2015 20:03:36 +0000 Subject: [PATCH 035/103] create config dir if not exist --- actions/dynamicdns | 1 + 1 file changed, 1 insertion(+) diff --git a/actions/dynamicdns b/actions/dynamicdns index a097b0146..23e1dab7d 100755 --- a/actions/dynamicdns +++ b/actions/dynamicdns @@ -84,6 +84,7 @@ doGetOpt() doWriteCFG() { + mkdir $CFGDIR 2> /dev/null #always write to the inactive config - needs to be enabled vi "start" command later FILE=$CFG_disabled From 5b71ce815c2b0bd57aeaa7a7f507180c6eb225b3 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Tue, 24 Feb 2015 08:05:54 +0000 Subject: [PATCH 036/103] cat on a empty string will block the script --- actions/dynamicdns | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/actions/dynamicdns b/actions/dynamicdns index 23e1dab7d..edeb03e03 100755 --- a/actions/dynamicdns +++ b/actions/dynamicdns @@ -40,7 +40,7 @@ doReadCFG() [ -f $CFG ] && FILE=$CFG if [ ! -z $FILE ];then - host=`cat $FILE 2> /dev/null |grep host |cut -d = -f 2` + host=`cat $FILE 2> /dev/null |grep host |cut -d = -f 2` server=`cat $FILE 2> /dev/null |grep server |cut -d = -f 2` user=`cat $FILE 2> /dev/null |grep user |cut -d = -f 2 |cut -d : -f 1` pass=`cat $FILE 2> /dev/null |grep user |cut -d = -f 2 |cut -d : -f 2` @@ -169,6 +169,7 @@ case $cmd in OLDIP=`cat $IPFILE` doGetWANIP echo $WANIP > $IPFILE + FILE="/tmp/none" [ -f $CFG_disabled ] && FILE=$CFG_disabled [ -f $CFG ] && FILE=$CFG cat $FILE |grep -v execute > ${FILE}.tmp From 76f9d087c9a91fcdff717091e88a3f27b34c6a39 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Tue, 24 Feb 2015 08:16:02 +0000 Subject: [PATCH 037/103] removed second password field from configure form and validate the form completly within clean function of configure form --- plinth/modules/dynamicdns/dynamicdns.py | 72 +++++++++++-------------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/plinth/modules/dynamicdns/dynamicdns.py b/plinth/modules/dynamicdns/dynamicdns.py index 8d0d05c90..46843ae00 100644 --- a/plinth/modules/dynamicdns/dynamicdns.py +++ b/plinth/modules/dynamicdns/dynamicdns.py @@ -98,11 +98,6 @@ class ConfigureForm(forms.Form): help_text=_('You should have been requested to select a password \ when you created the account.')) - dynamicdns_secret_repeat = TrimmedCharField( - label=_('repeat Password'), widget=forms.PasswordInput(), - required=False, - help_text=_('insert the password again to avoid typos.'),) - dynamicdns_ipurl = TrimmedCharField( label=_('IP check URL'), required=False, @@ -118,11 +113,10 @@ class ConfigureForm(forms.Form): def clean(self): cleaned_data = super(ConfigureForm, self).clean() dynamicdns_secret = cleaned_data.get("dynamicdns_secret") - dynamicdns_secret_repeat = cleaned_data.get("dynamicdns_secret_repeat") + old_dynamicdns_secret = self.initial['dynamicdns_secret'] - if dynamicdns_secret or dynamicdns_secret_repeat: - if dynamicdns_secret != dynamicdns_secret_repeat: - raise forms.ValidationError("password missmatch") + if not dynamicdns_secret and not old_dynamicdns_secret: + raise forms.ValidationError("please give a password") @login_required @@ -133,7 +127,7 @@ def configure(request): form = None if request.method == 'POST': - form = ConfigureForm(request.POST, prefix='dynamicdns') + form = ConfigureForm(request.POST, initial=status, prefix='dynamicdns') if form.is_valid(): _apply_changes(request, status, form.cleaned_data) status = get_status() @@ -213,42 +207,38 @@ def _apply_changes(request, old_status, new_status): LOGGER.info('New status is - %s', new_status) LOGGER.info('Old status was - %s', old_status) - if old_status['dynamicdns_secret'] == '' and \ - new_status['dynamicdns_secret'] == '': - messages.error(request, _('please give a password')) - else: - if new_status['dynamicdns_secret'] == '': - new_status['dynamicdns_secret'] = old_status['dynamicdns_secret'] + if new_status['dynamicdns_secret'] == '': + new_status['dynamicdns_secret'] = old_status['dynamicdns_secret'] - if new_status['dynamicdns_ipurl'] == '': - new_status['dynamicdns_ipurl'] = 'none' + if new_status['dynamicdns_ipurl'] == '': + new_status['dynamicdns_ipurl'] = 'none' - if old_status['dynamicdns_server'] != \ - new_status['dynamicdns_server'] or \ - old_status['dynamicdns_domain'] != \ - new_status['dynamicdns_domain'] or \ - old_status['dynamicdns_user'] != \ - new_status['dynamicdns_user'] or \ - old_status['dynamicdns_secret'] != \ - new_status['dynamicdns_secret'] or \ - old_status['dynamicdns_ipurl'] != \ - new_status['dynamicdns_ipurl'] or \ - old_status['enabled'] != \ - new_status['enabled']: + if old_status['dynamicdns_server'] != \ + new_status['dynamicdns_server'] or \ + old_status['dynamicdns_domain'] != \ + new_status['dynamicdns_domain'] or \ + old_status['dynamicdns_user'] != \ + new_status['dynamicdns_user'] or \ + old_status['dynamicdns_secret'] != \ + new_status['dynamicdns_secret'] or \ + old_status['dynamicdns_ipurl'] != \ + new_status['dynamicdns_ipurl'] or \ + old_status['enabled'] != \ + new_status['enabled']: - _run(['configure', '-s', new_status['dynamicdns_server'], - '-d', new_status['dynamicdns_domain'], - '-u', new_status['dynamicdns_user'], - '-p', new_status['dynamicdns_secret'], - '-I', new_status['dynamicdns_ipurl']]) + _run(['configure', '-s', new_status['dynamicdns_server'], + '-d', new_status['dynamicdns_domain'], + '-u', new_status['dynamicdns_user'], + '-p', new_status['dynamicdns_secret'], + '-I', new_status['dynamicdns_ipurl']]) - if old_status['enabled']: - _run(['stop']) - if new_status['enabled']: - _run(['start']) + if old_status['enabled']: + _run(['stop']) + if new_status['enabled']: + _run(['start']) - messages.success(request, - _('Dynamic DNS configuration is updated!')) + messages.success(request, + _('Dynamic DNS configuration is updated!')) def _run(arguments, superuser=False): From f35ab6a3b473b9a8ae939b0b7d9079375c9bed5f Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Sat, 28 Feb 2015 15:30:10 +0100 Subject: [PATCH 038/103] added a checkbox to make the password visible --- plinth/modules/dynamicdns/dynamicdns.py | 5 +++++ .../dynamicdns/templates/dynamicdns_configure.html | 13 ++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/plinth/modules/dynamicdns/dynamicdns.py b/plinth/modules/dynamicdns/dynamicdns.py index 46843ae00..e7a261376 100644 --- a/plinth/modules/dynamicdns/dynamicdns.py +++ b/plinth/modules/dynamicdns/dynamicdns.py @@ -98,6 +98,11 @@ class ConfigureForm(forms.Form): help_text=_('You should have been requested to select a password \ when you created the account.')) + showpw = forms.BooleanField(label=_('show password'), + required=False, + widget=forms.CheckboxInput + (attrs={'onclick': 'show_pass();'})) + dynamicdns_ipurl = TrimmedCharField( label=_('IP check URL'), required=False, diff --git a/plinth/modules/dynamicdns/templates/dynamicdns_configure.html b/plinth/modules/dynamicdns/templates/dynamicdns_configure.html index ade236ba9..630eabca7 100644 --- a/plinth/modules/dynamicdns/templates/dynamicdns_configure.html +++ b/plinth/modules/dynamicdns/templates/dynamicdns_configure.html @@ -30,5 +30,16 @@ - +{% endblock %} + +{% block page_js %} + {% endblock %} From 874d0bea18fdefd2d4dfb3d60adc157b3e4da036 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Sat, 28 Feb 2015 23:18:05 +0100 Subject: [PATCH 039/103] first version of java script based dynamic provider selection --- plinth/modules/dynamicdns/dynamicdns.py | 36 +++++- .../templates/dynamicdns_configure.html | 122 ++++++++++++++++-- 2 files changed, 143 insertions(+), 15 deletions(-) diff --git a/plinth/modules/dynamicdns/dynamicdns.py b/plinth/modules/dynamicdns/dynamicdns.py index e7a261376..bfca1ea2a 100644 --- a/plinth/modules/dynamicdns/dynamicdns.py +++ b/plinth/modules/dynamicdns/dynamicdns.py @@ -70,15 +70,44 @@ class TrimmedCharField(forms.CharField): class ConfigureForm(forms.Form): """Form to configure the dynamic DNS client""" - enabled = forms.BooleanField(label=_('Enable dynamicdns'), + enabled = forms.BooleanField(label=_('Enable Dynamic DNS'), required=False) + dynamicdns_service = forms.ChoiceField(label=_('Service type'), + help_text=_('Please choose a update protocol according to your provider.\ + We recommend the GnudIP protocol. If your provider does not \ + support the GnudIP protocol or your provider is not listed \ + you may use the update URL of your provider.'), + choices=(('1', 'GnudIP'), + ('2', 'noip.com'), + ('3', 'selfhost.bz'), + ('4', 'other Update URL'))) + dynamicdns_server = TrimmedCharField( - label=_('Server Address'), + label=_('GnudIP Server Address'), help_text=_('Example: gnudip.provider.org'), validators=[ validators.RegexValidator(r'^[\w-]{1,63}(\.[\w-]{1,63})*$', _('Invalid server name'))]) + + dynamicdns_update_url = TrimmedCharField( + label=_('Update URL'), + required=False, + help_text=_('The Variables $User, $Pass, $IP, $Domain may be used \ + within this URL.
Example URL:
\ + https://some.tld/up.php?us=$User&pw=$Pass&ip=$IP&dom=$Domain'), + validators=[ + validators.URLValidator(schemes=['http', 'https'])]) + + disable_SSL_cert_check = forms.BooleanField( + label=_('accept all SSL certificates'), + help_text=_('use this option if your provider uses\ + self signed certificates'), + required=False) + + use_http_basic_auth = forms.BooleanField( + label=_('use HTTP basic authentication'), + required=False) dynamicdns_domain = TrimmedCharField( label=_('Domain Name'), @@ -96,7 +125,8 @@ class ConfigureForm(forms.Form): label=_('Password'), widget=forms.PasswordInput(), required=False, help_text=_('You should have been requested to select a password \ - when you created the account.')) + when you created the account. Leave this field empty \ + if you want to keep your previous configured password.')) showpw = forms.BooleanField(label=_('show password'), required=False, diff --git a/plinth/modules/dynamicdns/templates/dynamicdns_configure.html b/plinth/modules/dynamicdns/templates/dynamicdns_configure.html index 630eabca7..da12c40e1 100644 --- a/plinth/modules/dynamicdns/templates/dynamicdns_configure.html +++ b/plinth/modules/dynamicdns/templates/dynamicdns_configure.html @@ -21,25 +21,123 @@ {% load bootstrap %} {% block content %} -

Configuration

+
{% csrf_token %} - {{ form|bootstrap }} + {% include 'bootstrapform/field.html' with field=form.enabled %} - +
+

Dynamic DNS type

+ {% include 'bootstrapform/field.html' with field=form.dynamicdns_service %} +
+ {% include 'bootstrapform/field.html' with field=form.dynamicdns_server %} +
+ +
+ {% include 'bootstrapform/field.html' with field=form.dynamicdns_update_url %} + {% include 'bootstrapform/field.html' with field=form.disable_SSL_cert_check %} + {% include 'bootstrapform/field.html' with field=form.use_http_basic_auth %} +
+ +

Account Information

+ {% include 'bootstrapform/field.html' with field=form.dynamicdns_domain %} + {% include 'bootstrapform/field.html' with field=form.dynamicdns_user %} + {% include 'bootstrapform/field.html' with field=form.dynamicdns_secret %} + {% include 'bootstrapform/field.html' with field=form.showpw %} + +

IP check URL

+ {% include 'bootstrapform/field.html' with field=form.dynamicdns_ipurl %} +
+ +
+ {% endblock %} {% block page_js %} - + + + + {% endblock %} From ffcfccb20f6b2be3255f6b966f8686a469e364e6 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 2 Mar 2015 20:56:46 +0100 Subject: [PATCH 040/103] beautyfied and refactored code --- actions/dynamicdns | 175 ++++++++++++++++++++++++++++----------------- 1 file changed, 108 insertions(+), 67 deletions(-) diff --git a/actions/dynamicdns b/actions/dynamicdns index edeb03e03..b591d4522 100755 --- a/actions/dynamicdns +++ b/actions/dynamicdns @@ -28,31 +28,11 @@ HELPERCFG="${CFGDIR}${TOOLNAME}-plinth.cfg" CRONJOB="/etc/cron.d/${TOOLNAME}" PIDFILE="/var/run/ez-ipupdate.pid" -doReadCFG() -{ - host="" - server="" - user="" - pass="" - IPURL="" - FILE="" - [ -f $CFG_disabled ] && FILE=$CFG_disabled - [ -f $CFG ] && FILE=$CFG - - if [ ! -z $FILE ];then - host=`cat $FILE 2> /dev/null |grep host |cut -d = -f 2` - server=`cat $FILE 2> /dev/null |grep server |cut -d = -f 2` - user=`cat $FILE 2> /dev/null |grep user |cut -d = -f 2 |cut -d : -f 1` - pass=`cat $FILE 2> /dev/null |grep user |cut -d = -f 2 |cut -d : -f 2` - fi - - if [ ! -z $HELPERCFG ];then - IPURL=`cat $HELPERCFG 2> /dev/null |grep URL |awk '{print $2}'` - fi -} - doGetOpt() { + basicauth=0 + ignoreCertError=0 + while getopts ":s:d:u:p:I:" opt; do case $opt in s) @@ -69,11 +49,24 @@ doGetOpt() ;; I) if [ "$OPTARG" != "$EMPTYSTRING" ];then - IPURL=$OPTARG + ipurl=$OPTARG else - IPURL="" + ipurl="" fi ;; + U) + if [ "$OPTARG" != "$EMPTYSTRING" ];then + updateurl=$OPTARG + else + updateurl="" + fi + ;; + b) + basicauth=$OPTARG + ;; + c) + ignoreCertError=$OPTARG + ;; \?) echo "Invalid option: -$OPTARG" >&2 exit 1 @@ -85,8 +78,8 @@ doGetOpt() doWriteCFG() { mkdir $CFGDIR 2> /dev/null - #always write to the inactive config - needs to be enabled vi "start" command later - FILE=$CFG_disabled + #always write to the inactive config - needs to be enabled via "start" command later + file=$CFG_disabled #reset the last update time echo 0 > $LASTUPDATE @@ -98,23 +91,28 @@ doWriteCFG() rm $STATUSFILE 2> /dev/null #find the interface (always the default gateway interface) - DEFAULT=`ip route |grep default |awk '{print $5}'` + default_interface=`ip route |grep default |awk '{print $5}'` #store the given options in ez-ipupdate compatible config file - echo "host=$host" > $FILE - echo "server=$server" >> $FILE - echo "user=${user}:${pass}" >> $FILE - echo "service-type=gnudip" >> $FILE - echo "retrys=3" >> $FILE - echo "wildcard" >> $FILE + echo "host=$host" > $file + echo "server=$server" >> $file + echo "user=${user}:${pass}" >> $file + echo "service-type=gnudip" >> $file + echo "retrys=3" >> $file + echo "wildcard" >> $file + + #store UPDATE URL params + echo "POSTURL $updateurl" > $HELPERCFG + echo "POSTAUTH $basicauth" >> $HELPERCFG + echo "POSTSSLIGNORE $ignoreCertError" >> $HELPERCFG #check if we are behind a NAT Router - echo "IPURL $IPURL" > $HELPERCFG - if [ -z $IPURL ];then + echo "IPURL $ipurl" >> $HELPERCFG + if [ -z $ipurl ];then echo "NAT unknown" >> $HELPERCFG else doGetWANIP - ISGLOBAL=`ip addr ls $DEFAULT | grep $WANIP` + ISGLOBAL=`ip addr ls $default_interface | grep $wanip` if [ -z $ISGLOBAL ];then #we are behind NAT echo "NAT yes" >> $HELPERCFG @@ -122,27 +120,64 @@ doWriteCFG() #we are directly connected echo "NAT no" >> $HELPERCFG #if this file is added ez-ipupdate will take ip form this interface - echo "interface=$DEFAULT" >> $FILE + echo "interface=$default_interface" >> $file #if this line is added to config file, ez-ipupdate will be launched on startup via init.d - echo "daemon" >> $FILE - echo "execute=$0 success" >> $FILE + echo "daemon" >> $file + echo "execute=$0 success" >> $file fi fi } +doReadCFG() +{ + host="" + server="" + user="" + pass="" + ipurl="" + file="" + [ -f $CFG_disabled ] && file=$CFG_disabled + [ -f $CFG ] && file=$CFG + + if [ ! -z $file ];then + host=`cat $file 2> /dev/null |grep host |cut -d = -f 2` + server=`cat $file 2> /dev/null |grep server |cut -d = -f 2` + user=`cat $file 2> /dev/null |grep user |cut -d = -f 2 |cut -d : -f 1` + pass=`cat $file 2> /dev/null |grep user |cut -d = -f 2 |cut -d : -f 2` + fi + + if [ ! -z $HELPERCFG ];then + ipurl=`cat $HELPERCFG 2> /dev/null |grep ^URL |awk '{print $2}'` + updateurl=`cat $HELPERCFG 2> /dev/null |grep POSTURL |awk '{print $2}'` + basicauth=`cat $HELPERCFG 2> /dev/null |grep POSTAUTH |awk '{print $2}'` + ignoreCertError=`cat $HELPERCFG 2> /dev/null |grep POSTSSLIGNORE |awk '{print $2}'` + fi +} + doGetWANIP() { - if [ ! -z $IPURL ];then - OUTFILE=`mktemp` - $WGET $WGETOPTIONS -O $OUTFILE $IPURL - WANIP=`cat $OUTFILE` - rm $OUTFILE + if [ ! -z $ipurl ];then + outfile=`mktemp` + $WGET $WGETOPTIONS -O $outfile $ipurl + wanip=`cat $outfile` + rm $outfile else #no WAN IP found because of missing check URL - WANIP=${NOIP} + wanip=${NOIP} fi } +doUpdate() +{ + if [ ! -z $server ];then + start-stop-daemon -S -x ${UPDATE_TOOL} -m -p ${PIDFILE} -- -c $file + fi + + if [ ! -z $updateurl ];then + echo "todo" + fi +} + cmd=$1 shift case $cmd in @@ -166,27 +201,27 @@ case $cmd in ;; update) doReadCFG - OLDIP=`cat $IPFILE` + oldip=`cat $IPFILE` doGetWANIP - echo $WANIP > $IPFILE - FILE="/tmp/none" - [ -f $CFG_disabled ] && FILE=$CFG_disabled - [ -f $CFG ] && FILE=$CFG - cat $FILE |grep -v execute > ${FILE}.tmp - mv ${FILE}.tmp ${FILE} - echo "execute=$0 success ${WANIP}" >> $FILE + echo $wanip > $IPFILE + cfgfile="/tmp/none" + [ -f $CFG_disabled ] && cfgfile=$CFG_disabled + [ -f $CFG ] && cfgfile=$CFG + cat $file |grep -v execute > ${cfgfile}.tmp + mv ${cfgfile}.tmp ${cfgfile} + echo "execute=$0 success ${wanip}" >> $cfgfile #if we know our WAN IP, only update if IP changes - if [ "${OLDIP}" != "${WANIP}" -a "${WANIP}" != ${NOIP} ];then - start-stop-daemon -S -x ${UPDATE_TOOL} -m -p ${PIDFILE} -- -c $FILE + if [ "${oldip}" != "${wanip}" -a "${wanip}" != ${NOIP} ];then + doUpdate fi #if we don't know our WAN IP do a blind update once a hour - if [ "${WANIP}" = ${NOIP} ];then - UPTIME=`cat /proc/uptime |cut -d . -f 1` + if [ "${wanip}" = ${NOIP} ];then + uptime=`cat /proc/uptime |cut -d . -f 1` LAST=0 [ -f ${LASTUPDATE} ] && LAST=`cat $LASTUPDATE` - DIFF=`expr $UPTIME - $LAST` - if [ $DIFF -gt $UPDATEMINUTESUNKNOWN ];then - start-stop-daemon -S -x ${UPDATE_TOOL} -m -p ${PIDFILE} -- -c $FILE + diff=`expr $uptime - $LAST` + if [ $diff -gt $UPDATEMINUTESUNKNOWN ];then + doUpdate fi fi ;; @@ -197,8 +232,8 @@ case $cmd in mv $CFG $CFG_disabled ;; success) - DATE=`date` - echo "last update done ($DATE)" > $STATUSFILE + date=`date` + echo "last update done ($date)" > $STATUSFILE cat /proc/uptime |awk '{print $1}' |cut -d . -f 1 > $LASTUPDATE #if called from cronjob, the current IP is given as parameter if [ $# -eq 1 ];then @@ -206,12 +241,12 @@ case $cmd in else #if called from ez-ipupdate daemon, no WAN IP is given as parameter doGetWANIP - echo $WANIP > $IPFILE + echo $wanip > $IPFILE fi ;; failed) - DATE=`date` - echo "last update failed ($DATE)" > $STATUSFILE + date=`date` + echo "last update failed ($date)" > $STATUSFILE ;; get-last-success) if [ -f $STATUSFILE ];then @@ -234,7 +269,10 @@ case $cmd in echo $host echo $user echo $pass - echo $IPURL + echo $ipurl + echo $updateurl + echo $basicauth + echo $ignoreCertError ;; get-timer) echo $UPDATEMINUTES @@ -251,6 +289,9 @@ case $cmd in echo "-u Account username" echo "-p Account Password" echo "-I A URL which returns the IP of the client who is requesting" + echo "-U The update URL (a HTTP GET on this URL will be done)" + echo "-c <1|0> disable SSL check on Update URL" + echo "-b <1|0> use HTTP basic auth on Update URL" echo "" echo "update do a one time update" echo "clean delete configuration" From 7e218b06ed6541445e360a64cf2b5507a3359ab4 Mon Sep 17 00:00:00 2001 From: Daniel Steglich Date: Mon, 2 Mar 2015 20:57:50 +0100 Subject: [PATCH 041/103] added dynamic form fields and fixed support for users without javascript support --- plinth/modules/dynamicdns/dynamicdns.py | 41 +++++- .../templates/dynamicdns_configure.html | 123 +++++++----------- 2 files changed, 84 insertions(+), 80 deletions(-) diff --git a/plinth/modules/dynamicdns/dynamicdns.py b/plinth/modules/dynamicdns/dynamicdns.py index bfca1ea2a..f8c869537 100644 --- a/plinth/modules/dynamicdns/dynamicdns.py +++ b/plinth/modules/dynamicdns/dynamicdns.py @@ -71,17 +71,19 @@ class TrimmedCharField(forms.CharField): class ConfigureForm(forms.Form): """Form to configure the dynamic DNS client""" enabled = forms.BooleanField(label=_('Enable Dynamic DNS'), - required=False) + required=False,widget=forms.CheckboxInput + (attrs={'onclick': 'mod_form();'})) dynamicdns_service = forms.ChoiceField(label=_('Service type'), help_text=_('Please choose a update protocol according to your provider.\ We recommend the GnudIP protocol. If your provider does not \ support the GnudIP protocol or your provider is not listed \ you may use the update URL of your provider.'), - choices=(('1', 'GnudIP'), + choices=(('1', 'GnuDIP'), ('2', 'noip.com'), ('3', 'selfhost.bz'), - ('4', 'other Update URL'))) + ('4', 'other Update URL')), + widget=forms.Select(attrs={"onChange":'mod_form()'})) dynamicdns_server = TrimmedCharField( label=_('GnudIP Server Address'), @@ -232,7 +234,27 @@ def get_status(): if len(details) > 5: status['dynamicdns_ipurl'] = details[5] else: - status['dynamicdns_secret'] = '' + status['dynamicdns_ipurl'] = '' + + if len(details) > 6: + status['dynamicdns_update_url'] = details[6] + else: + status['dynamicdns_update_url'] = '' + + if len(details) > 7: + status['disable_SSL_cert_check'] = details[7] + else: + status['disable_SSL_cert_check'] = '' + + if len(details) > 8: + status['use_http_basic_auth'] = details[8] + else: + status['use_http_basic_auth'] = '' + + if status['dynamicdns_server'] is not '': + status['dynamicdns_service'] = '1' + else: + status['dynamicdns_service'] = '4' return status @@ -258,6 +280,12 @@ def _apply_changes(request, old_status, new_status): new_status['dynamicdns_secret'] or \ old_status['dynamicdns_ipurl'] != \ new_status['dynamicdns_ipurl'] or \ + old_status['dynamicdns_update_url'] != \ + new_status['dynamicdns_update_url'] or \ + old_status['disable_SSL_cert_check'] != \ + new_status['disable_SSL_cert_check'] or \ + old_status['use_http_basic_auth'] != \ + new_status['use_http_basic_auth'] or \ old_status['enabled'] != \ new_status['enabled']: @@ -265,7 +293,10 @@ def _apply_changes(request, old_status, new_status): '-d', new_status['dynamicdns_domain'], '-u', new_status['dynamicdns_user'], '-p', new_status['dynamicdns_secret'], - '-I', new_status['dynamicdns_ipurl']]) + '-I', new_status['dynamicdns_ipurl'], + '-U', new_status['dynamicdns_update_url'], + '-c', new_status['disable_SSL_cert_check'], + '-b', new_status['use_http_basic_auth']]) if old_status['enabled']: _run(['stop']) diff --git a/plinth/modules/dynamicdns/templates/dynamicdns_configure.html b/plinth/modules/dynamicdns/templates/dynamicdns_configure.html index da12c40e1..3b0fe2b45 100644 --- a/plinth/modules/dynamicdns/templates/dynamicdns_configure.html +++ b/plinth/modules/dynamicdns/templates/dynamicdns_configure.html @@ -27,15 +27,21 @@ {% include 'bootstrapform/field.html' with field=form.enabled %} -
+
+

Dynamic DNS type

+
+ You have disabled Javascript. Dynamic form mode is disabled. Please fill + only "GnudIP Server Address" or "Update URL" field.

+
+