mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-21 07:55:00 +00:00
- Drop all the bash code. - Run the update URL code with same logic as before. Don't need to use action code for it. - Completely new way to handle configuration: using key/value store. Import old configuration once and delete it. - Use a glib scheduler instead of creating a cron job. - Store and show status from key/value store. - Handle multiple domains when getting/setting configuration and status. The UI still shows a single configuration form. To be improved later. - Catch and report all errors during the update process. - Drop all NAT detection code. - Drop selfhost.bz. German only, no free account, no proper TLS on domain, no easy to test. Existing accounts will continue to work with "other" as the service type. - For gnudip update code, add a timeout of 10 seconds, set a buffer size of two powers and fix handling error messages from server. Tests: - GnuDIP: - Upon submission of the form, the IP is updated if app is enabled. IP is not updated if app is disabled. - Every 5 minutes, check is made again and IP is updated. - If IP lookup URL is available, update calls are not made if the DNS is already up-to-date. - If IP lookup URL is not available, update calls are made unconditionally every 5 minutes. - For each of noip.com, freedns.afraid.org and other service: - Upon submission of the form, the IP is updated if app is enabled. IP is not updated if app is disabled. - Every 5 minutes, check is made again and IP is updated. - If IP lookup URL is available, update calls are not made if the DNS is already up-to-date. - If IP lookup URL is not available, update calls are made unconditionally every 5 minutes. - Form validation: - Domain field is always mandatory. - When type is selected as gnudip, the fields server, username, and password are mandatory. - When type is selected other than gnudip, the field update URL is mandatory. The rest are optional. - When the update URL contains a field contains <User>, username is mandatory. For <Pass>, password is mandatory. For <Ip>, ip_lookup_url is mandatory. - When use HTTP basic auth is checked, the fields username and password are mandatory. - Password is optional only if a previous password exists. If configuration is deleted from kvstore, password is mandatory. - Configuration import: Install dynamicdns without the patch. Add configuration with each of the service types. For GnuDIP service type, set two configurations with one with and without IP lookup URL. Update to code with the patch. Setup should run. - All fields in the configuration should be imported properly. - If the previous configuration is disabled, app should be disabled after import. Enabled otherwise. - Updating the IP address should work immediately after import. - Enable/Disable: when enabled, IP URL should be enabled every 5 minutes. When disabled, updates should not happen. - Status: - When status is removed from the DB, it should show that no status is available yet. - When the form is updated or update happens via the timer, the status is shown. It should show success for a proper update. Proper external IP address should be shown. - Set the server to localhost and submit. Status should show 'Server refused connection' message. IP address should be '-'. - Set the server to an unknown domain. Status should show 'Could not find server' message. IP address should be '-'. - Set the server to a known domain. Status should show 'Connection timed out' message. IP address should be '-'. - Last update time should keep increasing as time passes. - Backup/restore: - Functional tests. - Javascript: - When GnuDIP is selected as the type, the fields server, username, password, domain, show password, and IP lookup URL should be shown while other fields should be hidden. Same on page load with GnuDIP as pre-selected type. - When GnuDIP is not selected as the type, the fields update URL, accept all SSL certificates, use basic HTTP auth, domain name, username, password, show password, IP lookup URL and use IPv6 fields should be shown and rest of the fields should be hidden. Same on page load with non-GnuDIP as pre-selected type. - When show password is checked, password should be shown and when it is unchecked, password is masked. - When other service types are selected, the update URL values changes to the respective service's URL. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
146 lines
6.3 KiB
Python
146 lines
6.3 KiB
Python
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
"""
|
|
Forms for the dynamicsdns module.
|
|
"""
|
|
|
|
from django import forms
|
|
from django.core import validators
|
|
from django.utils.translation import gettext as _
|
|
from django.utils.translation import gettext_lazy
|
|
|
|
from plinth import cfg
|
|
from plinth.utils import format_lazy
|
|
|
|
|
|
class ConfigureForm(forms.Form):
|
|
"""Form to configure the Dynamic DNS client."""
|
|
help_update_url = \
|
|
gettext_lazy('The Variables <User>, <Pass>, <Ip>, '
|
|
'<Domain> may be used within the URL. For details '
|
|
'see the update URL templates of the example providers.')
|
|
help_service_type = \
|
|
gettext_lazy('Please choose an update protocol according to your '
|
|
'provider. If your provider does not support the GnuDIP '
|
|
'protocol or your provider is not listed you may use '
|
|
'the update URL of your provider.')
|
|
help_server = \
|
|
gettext_lazy('Please do not enter a URL here (like '
|
|
'"https://example.com/") but only the hostname of the '
|
|
'GnuDIP server (like "example.com").')
|
|
help_domain = format_lazy(
|
|
gettext_lazy('The public domain name you want to use to reach your '
|
|
'{box_name}.'), box_name=gettext_lazy(cfg.box_name))
|
|
help_disable_ssl_cert_check = \
|
|
gettext_lazy('Use this option if your provider uses self signed '
|
|
'certificates.')
|
|
help_use_http_basic_auth = \
|
|
gettext_lazy('If this option is selected, your username and password '
|
|
'will be used for HTTP basic authentication.')
|
|
help_password = \
|
|
gettext_lazy('Leave this field empty if you want to keep your '
|
|
'current password.')
|
|
help_ip_lookup_url = format_lazy(
|
|
gettext_lazy('Optional Value. If your {box_name} is not connected '
|
|
'directly to the Internet (i.e. connected to a NAT '
|
|
'router) this URL is used to determine the real '
|
|
'IP address. The URL should simply return the IP where '
|
|
'the client comes from (example: '
|
|
'https://ddns.freedombox.org/ip/).'),
|
|
box_name=gettext_lazy(cfg.box_name))
|
|
help_username = \
|
|
gettext_lazy('The username that was used when the account was '
|
|
'created.')
|
|
|
|
provider_choices = (('gnudip', gettext_lazy('GnuDIP')),
|
|
('noip.com', 'noip.com'), ('freedns.afraid.org',
|
|
'freedns.afraid.org'),
|
|
('other', gettext_lazy('Other update URL')))
|
|
|
|
service_type = forms.ChoiceField(label=gettext_lazy('Service Type'),
|
|
help_text=help_service_type,
|
|
choices=provider_choices)
|
|
|
|
server = forms.CharField(
|
|
label=gettext_lazy('GnuDIP Server Address'), required=False,
|
|
help_text=help_server, validators=[
|
|
validators.RegexValidator(r'^[\w-]{1,63}(\.[\w-]{1,63})*$',
|
|
gettext_lazy('Invalid server name'))
|
|
])
|
|
|
|
update_url = forms.CharField(label=gettext_lazy('Update URL'),
|
|
required=False, help_text=help_update_url)
|
|
|
|
disable_ssl_cert_check = forms.BooleanField(
|
|
label=gettext_lazy('Accept all SSL certificates'),
|
|
help_text=help_disable_ssl_cert_check, required=False)
|
|
|
|
use_http_basic_auth = forms.BooleanField(
|
|
label=gettext_lazy('Use HTTP basic authentication'),
|
|
help_text=help_use_http_basic_auth, required=False)
|
|
|
|
domain = forms.CharField(
|
|
label=gettext_lazy('Domain Name'), help_text=help_domain,
|
|
required=True, validators=[
|
|
validators.RegexValidator(r'^[\w-]{1,63}(\.[\w-]{1,63})*$',
|
|
gettext_lazy('Invalid domain name'))
|
|
])
|
|
|
|
username = forms.CharField(label=gettext_lazy('Username'), required=False,
|
|
help_text=help_username)
|
|
|
|
password = forms.CharField(label=gettext_lazy('Password'),
|
|
widget=forms.PasswordInput(), required=False,
|
|
help_text=help_password)
|
|
|
|
show_password = forms.BooleanField(label=gettext_lazy('Show password'),
|
|
required=False)
|
|
|
|
ip_lookup_url = forms.CharField(
|
|
label=gettext_lazy('URL to look up public IP'), required=False,
|
|
help_text=help_ip_lookup_url,
|
|
validators=[validators.URLValidator(schemes=['http', 'https'])])
|
|
|
|
use_ipv6 = forms.BooleanField(
|
|
label=gettext_lazy('Use IPv6 instead of IPv4'), required=False)
|
|
|
|
def clean(self):
|
|
"""Further validate and transform field data."""
|
|
cleaned_data = super().clean()
|
|
|
|
# Domain name is not case sensitive, but Let's Encrypt
|
|
# certificate paths use lower-case domain name.
|
|
cleaned_data['domain'] = cleaned_data['domain'].lower()
|
|
|
|
update_url = cleaned_data.get('update_url')
|
|
password = cleaned_data.get('password')
|
|
service_type = cleaned_data.get('service_type')
|
|
old_password = self.initial.get('password')
|
|
|
|
if not password:
|
|
# If password is not set, use old password
|
|
cleaned_data['password'] = old_password
|
|
|
|
message = _('This field is required.')
|
|
if service_type == 'gnudip':
|
|
for field_name in ['server', 'username', 'password']:
|
|
if not cleaned_data.get(field_name):
|
|
self.add_error(field_name, message)
|
|
else:
|
|
if not update_url:
|
|
self.add_error('update_url', message)
|
|
|
|
param_map = (('username', '<User>'), ('password', '<Pass>'),
|
|
('ip_lookup_url', '<Ip>'))
|
|
for field_name, param in param_map:
|
|
if (update_url and param in update_url
|
|
and not cleaned_data.get(field_name)):
|
|
self.add_error(field_name, message)
|
|
|
|
if cleaned_data.get('use_http_basic_auth'):
|
|
for field_name in ('username', 'password'):
|
|
if not cleaned_data.get(field_name):
|
|
self.add_error(field_name, message)
|
|
|
|
del cleaned_data['show_password']
|
|
return cleaned_data
|