Merge pull request #313 from elnappo/django111

Update to Django 1.11 LTS
This commit is contained in:
TW 2018-01-30 17:56:16 +01:00 committed by GitHub
commit 1a7f38a1c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 169 additions and 192 deletions

View File

@ -23,23 +23,23 @@ env:
- TEST_OPTS="" - TEST_OPTS=""
- COVERAGE="" - COVERAGE=""
matrix: matrix:
- DJANGO=1.8.1 - DJANGO=1.11
matrix: matrix:
exclude: exclude:
- python: "2.7" - python: "2.7"
env: DJANGO=1.8.1 env: DJANGO=1.11
- python: "3.6" - python: "3.6"
env: DJANGO=1.8.1 env: DJANGO=1.11
- python: "3.6-dev"
env: DJANGO=1.8.1
include:
- python: "2.7"
env: DJANGO=1.8.1 COVERAGE="coverage run -m" TEST_K="not ddns_client" TEST_OPTS="--pep8"
- python: "3.6"
env: DJANGO=1.8.18
- python: "3.6-dev" - python: "3.6-dev"
env: DJANGO=1.11 env: DJANGO=1.11
include:
- python: "2.7"
env: DJANGO=1.11 COVERAGE="coverage run -m" TEST_K="not ddns_client" TEST_OPTS="--pep8"
- python: "3.6"
env: DJANGO=1.11
- python: "3.6-dev"
env: DJANGO=2.0
install: install:
- ./scripts/travis/install.sh - ./scripts/travis/install.sh

View File

@ -6,8 +6,7 @@ from __future__ import print_function
import pytest import pytest
from django.core.urlresolvers import reverse from django.urls import reverse
USERNAME = 'test' USERNAME = 'test'
PASSWORD = 'pass' PASSWORD = 'pass'
@ -29,17 +28,16 @@ def test_views_anon(client):
assert response.status_code == status_code assert response.status_code == status_code
def test_views_logged_in(client): @pytest.mark.parametrize("view,view_kwargs,status_code", (
client.login(username=USERNAME, password=PASSWORD) ('account_profile', dict(), 200),
for view, kwargs, status_code in [ ('account_settings', dict(), 200),
('account_profile', dict(), 200), ('account_delete', dict(), 200),
('account_settings', dict(), 200), ('registration_disallowed', dict(), 200),
('account_delete', dict(), 200), ('registration_complete', dict(), 200),
('registration_disallowed', dict(), 200), ('registration_register', dict(), 302),
('registration_complete', dict(), 200), ('registration_activation_complete', dict(), 200),
('registration_register', dict(), 200), ))
('registration_activation_complete', dict(), 200), def test_views_logged_in(client, view, view_kwargs, status_code):
]: assert client.login(username=USERNAME, password=PASSWORD)
print("%s, %s, %s" % (view, kwargs, status_code)) response = client.get(reverse(view, kwargs=view_kwargs))
response = client.get(reverse(view, kwargs=kwargs)) assert response.status_code == status_code
assert response.status_code == status_code

View File

@ -19,7 +19,7 @@ class UserProfile(models.Model):
stuff we need additionally to what Django stores in User model stuff we need additionally to what Django stores in User model
""" """
user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key=True, related_name='profile', user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key=True, related_name='profile',
verbose_name=_('user')) verbose_name=_('user'), on_delete=models.CASCADE)
language = models.CharField(max_length=10, choices=settings.LANGUAGES, language = models.CharField(max_length=10, choices=settings.LANGUAGES,
default='', blank=True, null=True, default='', blank=True, null=True,
verbose_name=_('language')) verbose_name=_('language'))

View File

@ -14,7 +14,7 @@
{{ form|bootstrap_horizontal:"col-sm-3 col-lg-3" }} {{ form|bootstrap_horizontal:"col-sm-3 col-lg-3" }}
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-3 col-sm-8"> <div class="col-sm-offset-3 col-sm-8">
<input type="submit" class="btn btn-primary" value="{% trans 'Change my password' %}" /> <a href="{% url 'django.contrib.auth.views.password_reset' %}">{% trans 'Forgot your password?' %}</a> <input type="submit" class="btn btn-primary" value="{% trans 'Change my password' %}" /> <a href="{% url 'password_reset' %}">{% trans 'Forgot your password?' %}</a>
</div> </div>
</div> </div>
</form> </form>

View File

@ -1,4 +1,3 @@
from django.conf.urls import patterns
from django.conf.urls import url from django.conf.urls import url
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
@ -8,8 +7,7 @@ from registration.backends.default.views import RegistrationView
from .views import UserProfileView, DeleteUserView, UserChangePasswordView from .views import UserProfileView, DeleteUserView, UserChangePasswordView
urlpatterns = patterns( urlpatterns = (
'',
url(r'^profile/', UserProfileView.as_view(), name="account_profile"), url(r'^profile/', UserProfileView.as_view(), name="account_profile"),
url(r'^settings/', UserChangePasswordView.as_view(), name='account_settings'), url(r'^settings/', UserChangePasswordView.as_view(), name='account_settings'),
url(r'^delete/', DeleteUserView.as_view(), name="account_delete"), url(r'^delete/', DeleteUserView.as_view(), name="account_delete"),

View File

@ -7,7 +7,7 @@ from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect from django.views.decorators.csrf import csrf_protect
from django.views.decorators.debug import sensitive_post_parameters from django.views.decorators.debug import sensitive_post_parameters
from django.core.urlresolvers import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.shortcuts import redirect from django.shortcuts import redirect
from django.contrib import messages from django.contrib import messages
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _

View File

@ -7,7 +7,7 @@ import pytest
import base64 import base64
from netaddr import IPSet, IPAddress, IPNetwork from netaddr import IPSet, IPAddress, IPNetwork
from django.core.urlresolvers import reverse from django.urls import reverse
from nsupdate.main.dnstools import query_ns, FQDN from nsupdate.main.dnstools import query_ns, FQDN
from nsupdate.main.models import Domain from nsupdate.main.models import Domain

View File

@ -10,7 +10,7 @@
{% if form.errors %} {% if form.errors %}
<p>{% trans "Your username and password didn't match. Please try again." %}</p> <p>{% trans "Your username and password didn't match. Please try again." %}</p>
{% endif %} {% endif %}
<form class="form-horizontal" role="form" method="post" action="{% url 'django.contrib.auth.views.login' %}"> <form class="form-horizontal" role="form" method="post" action="{% url 'login' %}">
{% csrf_token %} {% csrf_token %}
{{ form|bootstrap_horizontal:"col-sm-3 col-lg-3" }} {{ form|bootstrap_horizontal:"col-sm-3 col-lg-3" }}
<div class="form-group"> <div class="form-group">
@ -21,7 +21,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-3 col-sm-9"> <div class="col-sm-offset-3 col-sm-9">
<input type="submit" class="btn btn-primary" value="{% trans 'Log in' %}" /> <a href="{% url 'django.contrib.auth.views.password_reset' %}">{% trans 'Forgot your password?' %}</a> <input type="submit" class="btn btn-primary" value="{% trans 'Log in' %}" /> <a href="{% url 'password_reset' %}">{% trans 'Forgot your password?' %}</a>
<p></p> <p></p>
<p><a href="{% url 'registration_register' %}">{% trans "Sign up for a new account..." %}</a></p> <p><a href="{% url 'registration_register' %}">{% trans "Sign up for a new account..." %}</a></p>
</div> </div>

View File

@ -6,7 +6,7 @@
<div class="container"> <div class="container">
<div class="form-signin"> <div class="form-signin">
<p>{% trans "Thanks for spending some quality time with the Web site today." %}</p> <p>{% trans "Thanks for spending some quality time with the Web site today." %}</p>
<p><a href="{% url 'django.contrib.auth.views.login' %}">{% trans 'Log in again' %}</a></p> <p><a href="{% url 'login' %}">{% trans 'Log in again' %}</a></p>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -1,21 +1,22 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.conf.urls import patterns, url from django.conf.urls import url
from django.contrib.auth.views import login, logout, password_reset, password_reset_done, \
password_reset_confirm, password_reset_complete
urlpatterns = patterns( urlpatterns = (
'',
# login and logout url # login and logout url
url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}, name='login'), url(r'^login/$', login, {'template_name': 'login.html'}, name='login'),
# or use 'django.contrib.auth.views.logout' with template 'logout.html # or use logout with template 'logout.html'
url(r'^logout/$', 'django.contrib.auth.views.logout_then_login', name='logout'), url(r'^logout/$', logout, name='logout'),
# password reset urls # password reset urls
url(r'^password_reset/$', 'django.contrib.auth.views.password_reset', url(r'^password_reset/$', password_reset, {'template_name': 'password_reset.html'},
{'template_name': 'password_reset.html'}, name='password_reset'), name='password_reset'),
url(r'^password_reset_done/$', 'django.contrib.auth.views.password_reset_done', url(r'^password_reset_done/$', password_reset_done,
{'template_name': 'password_reset_done.html'}, name='password_reset_done'), {'template_name': 'password_reset_done.html'}, name='password_reset_done'),
url(r'^password_reset_confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$', url(r'^password_reset_confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$',
'django.contrib.auth.views.password_reset_confirm', password_reset_confirm, {'template_name': 'password_reset_confirm.html'},
{'template_name': 'password_reset_confirm.html'}, name='password_reset_confirm'), name='password_reset_confirm'),
url(r'^password_reset_complete/$', 'django.contrib.auth.views.password_reset_complete', url(r'^password_reset_complete/$', password_reset_complete,
{'template_name': 'password_reset_complete.html'}, name='password_reset_complete'), {'template_name': 'password_reset_complete.html'}, name='password_reset_complete'),
) )

View File

@ -6,7 +6,7 @@ from __future__ import print_function
import pytest import pytest
from django.core.urlresolvers import reverse from django.urls import reverse
USERNAME = 'test' USERNAME = 'test'

View File

@ -20,7 +20,6 @@ from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import python_2_unicode_compatible from django.utils.encoding import python_2_unicode_compatible
from django.utils.six import text_type from django.utils.six import text_type
from . import dnstools from . import dnstools
RESULT_MSG_LEN = 255 RESULT_MSG_LEN = 255
@ -47,7 +46,7 @@ class BlacklistedHost(models.Model):
created_by = models.ForeignKey( created_by = models.ForeignKey(
settings.AUTH_USER_MODEL, settings.AUTH_USER_MODEL,
related_name='blacklisted_domains', related_name='blacklisted_domains',
verbose_name=_('created by')) verbose_name=_('created by'), on_delete=models.CASCADE)
def __str__(self): def __str__(self):
return self.name_re return self.name_re
@ -64,6 +63,7 @@ def host_blacklist_validator(value):
from collections import namedtuple from collections import namedtuple
UpdateAlgorithm = namedtuple("update_algorithm", "bitlength bind_name") UpdateAlgorithm = namedtuple("update_algorithm", "bitlength bind_name")
UPDATE_ALGORITHM_DEFAULT = 'HMAC_SHA512' UPDATE_ALGORITHM_DEFAULT = 'HMAC_SHA512'
@ -128,7 +128,8 @@ class Domain(models.Model):
last_update = models.DateTimeField(_("last update"), auto_now=True) last_update = models.DateTimeField(_("last update"), auto_now=True)
created = models.DateTimeField(_("created at"), auto_now_add=True) created = models.DateTimeField(_("created at"), auto_now_add=True)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='domains', verbose_name=_("created by")) created_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='domains', verbose_name=_("created by"),
on_delete=models.CASCADE)
def __str__(self): def __str__(self):
return self.name return self.name
@ -149,7 +150,7 @@ class Domain(models.Model):
class Meta: class Meta:
verbose_name = _('domain') verbose_name = _('domain')
verbose_name_plural = _('domains') verbose_name_plural = _('domains')
ordering = ('name', ) ordering = ('name',)
@python_2_unicode_compatible @python_2_unicode_compatible
@ -249,14 +250,15 @@ class Host(models.Model):
last_update = models.DateTimeField(_("last update"), auto_now=True) last_update = models.DateTimeField(_("last update"), auto_now=True)
created = models.DateTimeField(_("created at"), auto_now_add=True) created = models.DateTimeField(_("created at"), auto_now_add=True)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='hosts', verbose_name=_("created by"),) created_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='hosts', verbose_name=_("created by"),
on_delete=models.CASCADE)
def __str__(self): def __str__(self):
return u"%s.%s" % (self.name, self.domain.name) return u"%s.%s" % (self.name, self.domain.name)
class Meta(object): class Meta(object):
unique_together = (('name', 'domain'), ) unique_together = (('name', 'domain'),)
index_together = (('name', 'domain'), ) index_together = (('name', 'domain'),)
verbose_name = _('host') verbose_name = _('host')
verbose_name_plural = _('hosts') verbose_name_plural = _('hosts')
ordering = ('domain', 'name') # groupby domain and sort by name ordering = ('domain', 'name') # groupby domain and sort by name
@ -345,10 +347,11 @@ def pre_delete_host(sender, **kwargs):
except (dnstools.Timeout, dnstools.NameServerNotAvailable): except (dnstools.Timeout, dnstools.NameServerNotAvailable):
# well, we tried to clean up, but we didn't reach the nameserver # well, we tried to clean up, but we didn't reach the nameserver
pass pass
except (dnstools.DnsUpdateError, ): except (dnstools.DnsUpdateError,):
# e.g. PeerBadSignature if host is protected by a key we do not have # e.g. PeerBadSignature if host is protected by a key we do not have
pass pass
pre_delete.connect(pre_delete_host, sender=Host) pre_delete.connect(pre_delete_host, sender=Host)
@ -360,10 +363,11 @@ def post_save_host(sender, **kwargs):
except (dnstools.Timeout, dnstools.NameServerNotAvailable): except (dnstools.Timeout, dnstools.NameServerNotAvailable):
# well, we tried to clean up, but we didn't reach the nameserver # well, we tried to clean up, but we didn't reach the nameserver
pass pass
except (dnstools.DnsUpdateError, ): except (dnstools.DnsUpdateError,):
# e.g. PeerBadSignature if host is protected by a key we do not have # e.g. PeerBadSignature if host is protected by a key we do not have
pass pass
post_save.connect(post_save_host, sender=Host) post_save.connect(post_save_host, sender=Host)
@ -411,7 +415,7 @@ class RelatedHost(models.Model):
return u"%s.%s" % (self.name, text_type(self.main_host)) return u"%s.%s" % (self.name, text_type(self.main_host))
class Meta(object): class Meta(object):
unique_together = (('name', 'main_host'), ) unique_together = (('name', 'main_host'),)
verbose_name = _('related host') verbose_name = _('related host')
verbose_name_plural = _('related hosts') verbose_name_plural = _('related hosts')
ordering = ('main_host', 'name') ordering = ('main_host', 'name')
@ -475,7 +479,7 @@ class ServiceUpdater(models.Model):
created_by = models.ForeignKey( created_by = models.ForeignKey(
settings.AUTH_USER_MODEL, settings.AUTH_USER_MODEL,
related_name='serviceupdater', related_name='serviceupdater',
verbose_name=_("created by")) verbose_name=_("created by"), on_delete=models.CASCADE)
def __str__(self): def __str__(self):
return self.name return self.name
@ -525,10 +529,10 @@ class ServiceUpdaterHostConfig(models.Model):
created_by = models.ForeignKey( created_by = models.ForeignKey(
settings.AUTH_USER_MODEL, settings.AUTH_USER_MODEL,
related_name='serviceupdaterhostconfigs', related_name='serviceupdaterhostconfigs',
verbose_name=_("created by")) verbose_name=_("created by"), on_delete=models.CASCADE)
def __str__(self): def __str__(self):
return u"%s (%s)" % (self.hostname, self.service.name, ) return u"%s (%s)" % (self.hostname, self.service.name,)
class Meta(object): class Meta(object):
verbose_name = _('service updater host config') verbose_name = _('service updater host config')

View File

@ -2,7 +2,7 @@
main app url dispatching main app url dispatching
""" """
from django.conf.urls import patterns, url from django.conf.urls import url
from .views import ( from .views import (
HomeView, OverviewView, HostView, AddHostView, DeleteHostView, AboutView, GenerateSecretView, GenerateNSSecretView, HomeView, OverviewView, HostView, AddHostView, DeleteHostView, AboutView, GenerateSecretView, GenerateNSSecretView,
@ -14,8 +14,7 @@ from ..api.views import (
NicDeleteView, AuthorizedNicDeleteView) NicDeleteView, AuthorizedNicDeleteView)
urlpatterns = patterns( urlpatterns = (
'',
# interactive web ui # interactive web ui
url(r'^$', HomeView.as_view(), name="home"), url(r'^$', HomeView.as_view(), name="home"),
url(r'^about/$', AboutView.as_view(), name="about"), url(r'^about/$', AboutView.as_view(), name="about"),

View File

@ -16,7 +16,7 @@ from django.contrib.auth.decorators import login_required
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib import messages from django.contrib import messages
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.core.urlresolvers import reverse from django.urls import reverse
from django.http import Http404 from django.http import Http404
from django import template from django import template
from django.utils.timezone import now from django.utils.timezone import now
@ -195,7 +195,7 @@ class OverviewView(TemplateView):
.only("name", "comment", "available", "client_faults", "server_faults", "abuse_blocked", "abuse", .only("name", "comment", "available", "client_faults", "server_faults", "abuse_blocked", "abuse",
"last_update_ipv4", "tls_update_ipv4", "last_update_ipv6", "tls_update_ipv6", "domain__name") "last_update_ipv4", "tls_update_ipv4", "last_update_ipv6", "tls_update_ipv6", "domain__name")
context['your_domains'] = Domain.objects.filter( context['your_domains'] = Domain.objects.filter(
created_by=self.request.user).select_related("created_by__username")\ created_by=self.request.user).select_related("created_by__profile")\
.only("name", "public", "available", "comment", "created_by__username") .only("name", "public", "available", "comment", "created_by__username")
context['public_domains'] = Domain.objects.filter( context['public_domains'] = Domain.objects.filter(
public=True).exclude(created_by=self.request.user).select_related("created_by")\ public=True).exclude(created_by=self.request.user).select_related("created_by")\
@ -215,7 +215,7 @@ class AddHostView(CreateView):
def get_success_url(self): def get_success_url(self):
return reverse('generate_secret_view', args=(self.object.pk,)) return reverse('generate_secret_view', args=(self.object.pk,))
def get_form(self, form_class): def get_form(self, form_class=None):
form = super(AddHostView, self).get_form(form_class) form = super(AddHostView, self).get_form(form_class)
form.fields['domain'].queryset = Domain.objects.filter( form.fields['domain'].queryset = Domain.objects.filter(
Q(created_by=self.request.user) | Q(public=True)) Q(created_by=self.request.user) | Q(public=True))
@ -347,7 +347,7 @@ class AddRelatedHostView(CreateView):
def get_success_url(self): def get_success_url(self):
return reverse('related_host_overview', args=(self.object.main_host.pk, )) return reverse('related_host_overview', args=(self.object.main_host.pk, ))
def get_form(self, form_class): def get_form(self, form_class=None):
form = super(AddRelatedHostView, self).get_form(form_class) form = super(AddRelatedHostView, self).get_form(form_class)
return form return form

View File

@ -4,8 +4,6 @@ dealing with domains (Domain records in our database)
import dns.resolver import dns.resolver
from optparse import make_option
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.core.mail import send_mail from django.core.mail import send_mail
from django.db import transaction from django.db import transaction
@ -15,7 +13,6 @@ from nsupdate.main.models import Domain
from nsupdate.main.dnstools import FQDN, query_ns, NameServerNotAvailable from nsupdate.main.dnstools import FQDN, query_ns, NameServerNotAvailable
from nsupdate.utils.mail import translate_for_user, send_mail_to_user from nsupdate.utils.mail import translate_for_user, send_mail_to_user
MSG = _("""\ MSG = _("""\
Your domain: %(domain)s (comment: %(comment)s) Your domain: %(domain)s (comment: %(comment)s)
@ -68,20 +65,17 @@ def check_dns(domain):
class Command(BaseCommand): class Command(BaseCommand):
help = 'deal with domains' help = 'deal with domains'
option_list = BaseCommand.option_list + ( def add_arguments(self, parser):
make_option('--check', parser.add_argument('--check',
action='store_true', action='store_true',
dest='check', dest='check',
default=False, default=False,
help='check whether nameserver for domain is reachable and answers queries', help='check whether nameserver for domain is reachable and answers queries')
), parser.add_argument('--notify-user',
make_option('--notify-user', action='store_true',
action='store_true', dest='notify_user',
dest='notify_user', default=False,
default=False, help='notify the user by email when domain gets flagged as unavailable')
help='notify the user by email when domain gets flagged as unavailable',
),
)
def handle(self, *args, **options): def handle(self, *args, **options):
check = options['check'] check = options['check']
@ -105,6 +99,6 @@ class Command(BaseCommand):
subject = subject % dict(domain=domain) subject = subject % dict(domain=domain)
msg = msg % dict(domain=domain, comment=comment) msg = msg % dict(domain=domain, comment=comment)
send_mail_to_user(creator, subject, msg) send_mail_to_user(creator, subject, msg)
msg = "setting unavailable flag for domain %s (created by %s)\n" % (domain, creator, ) msg = "setting unavailable flag for domain %s (created by %s)\n" % (domain, creator,)
self.stdout.write(msg) self.stdout.write(msg)
d.save() d.save()

View File

@ -4,8 +4,6 @@ dealing with the fault counters and available/abuse/abuse_blocked flags
import traceback import traceback
from optparse import make_option
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.core.mail import send_mail from django.core.mail import send_mail
from django.db import transaction from django.db import transaction
@ -14,7 +12,6 @@ from django.utils.translation import ugettext_lazy as _
from nsupdate.main.models import Host from nsupdate.main.models import Host
from nsupdate.utils.mail import translate_for_user, send_mail_to_user from nsupdate.utils.mail import translate_for_user, send_mail_to_user
ABUSE_MSG = _("""\ ABUSE_MSG = _("""\
Your host: %(fqdn)s (comment: %(comment)s) Your host: %(fqdn)s (comment: %(comment)s)
@ -52,63 +49,53 @@ Notes:
class Command(BaseCommand): class Command(BaseCommand):
help = 'deal with the faults counters' help = 'deal with the faults counters'
option_list = BaseCommand.option_list + ( def add_arguments(self, parser):
make_option('--show-server', parser.add_argument('--show-server',
action='store_true', action='store_true',
dest='show_server', dest='show_server',
default=False, default=False,
help='show server fault counters', help='show server fault counters')
), parser.add_argument('--show-client',
make_option('--show-client', action='store_true',
action='store_true', dest='show_client',
dest='show_client', default=False,
default=False, help='show client fault counters')
help='show client fault counters', parser.add_argument('--reset-server',
), action='store_true',
make_option('--reset-server', dest='reset_server',
action='store_true', default=False,
dest='reset_server', help='reset the server fault counters of all hosts')
default=False, parser.add_argument('--reset-client',
help='reset the server fault counters of all hosts', action='store_true',
), dest='reset_client',
make_option('--reset-client', default=False,
action='store_true', help='reset the client fault counters of all hosts')
dest='reset_client', parser.add_argument('--reset-abuse',
default=False, action='store_true',
help='reset the client fault counters of all hosts', dest='reset_abuse',
), default=False,
make_option('--reset-abuse', help='reset the abuse flag (to False) of all hosts')
action='store_true', parser.add_argument('--reset-abuse-blocked',
dest='reset_abuse', action='store_true',
default=False, dest='reset_abuse_blocked',
help='reset the abuse flag (to False) of all hosts', default=False,
), help='reset the abuse_blocked flag (to False) of all hosts')
make_option('--reset-abuse-blocked', parser.add_argument('--reset-available',
action='store_true', action='store_true',
dest='reset_abuse_blocked', dest='reset_available',
default=False, default=False,
help='reset the abuse_blocked flag (to False) of all hosts', help='reset the available flag (to True) of all hosts')
), parser.add_argument('--flag-abuse',
make_option('--reset-available', action='store',
action='store_true', dest='flag_abuse',
dest='reset_available', default=None,
default=False, type=int,
help='reset the available flag (to True) of all hosts', help='if client faults > N then set abuse flag and reset client faults')
), parser.add_argument('--notify-user',
make_option('--flag-abuse', action='store_true',
action='store', dest='notify_user',
dest='flag_abuse', default=False,
default=None, help='notify the user by email when host gets flagged for abuse')
type='int',
help='if client faults > N then set abuse flag and reset client faults',
),
make_option('--notify-user',
action='store_true',
dest='notify_user',
default=False,
help='notify the user by email when host gets flagged for abuse',
),
)
def handle(self, *args, **options): def handle(self, *args, **options):
show_client = options['show_client'] show_client = options['show_client']
@ -129,7 +116,7 @@ class Command(BaseCommand):
output += u"%-6d " % h.client_faults output += u"%-6d " % h.client_faults
if show_server: if show_server:
output += u"%-6d " % h.server_faults output += u"%-6d " % h.server_faults
output += u"%s %s\n" % (h.created_by.username, h.get_fqdn(), ) output += u"%s %s\n" % (h.created_by.username, h.get_fqdn(),)
self.stdout.write(output) self.stdout.write(output)
if (flag_abuse is not None or reset_client or reset_server or if (flag_abuse is not None or reset_client or reset_server or
reset_available or reset_abuse or reset_abuse_blocked): reset_available or reset_abuse or reset_abuse_blocked):
@ -166,7 +153,7 @@ class Command(BaseCommand):
h.save() h.save()
except Exception: except Exception:
try: try:
msg = u"The following Exception occurred when processing host %s!\n" % (h.get_fqdn(), ) msg = u"The following Exception occurred when processing host %s!\n" % (h.get_fqdn(),)
self.stderr.write(msg) self.stderr.write(msg)
except Exception: except Exception:
pass pass

View File

@ -3,7 +3,6 @@ dealing with hosts (Host records in our database)
""" """
from datetime import datetime from datetime import datetime
from optparse import make_option
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.db import transaction from django.db import transaction
@ -132,20 +131,17 @@ def check_staleness(h):
class Command(BaseCommand): class Command(BaseCommand):
help = 'deal with hosts' help = 'deal with hosts'
option_list = BaseCommand.option_list + ( def add_arguments(self, parser):
make_option('--stale-check', parser.add_argument('--stale-check',
action='store_true', action='store_true',
dest='stale_check', dest='stale_check',
default=False, default=False,
help='check whether the host has been updated recently, increase staleness counter if not', help='check whether the host has been updated recently, increase staleness counter if not')
), parser.add_argument('--notify-user',
make_option('--notify-user', action='store_true',
action='store_true', dest='notify_user',
dest='notify_user', default=False,
default=False, help='notify the user by email when staleness counter increases')
help='notify the user by email when staleness counter increases',
),
)
def handle(self, *args, **options): def handle(self, *args, **options):
stale_check = options['stale_check'] stale_check = options['stale_check']

View File

@ -4,13 +4,13 @@ reinitialize the test user account (and clean up)
from django.conf import settings from django.conf import settings
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.core.management.base import NoArgsCommand from django.core.management.base import BaseCommand
class Command(NoArgsCommand): class Command(BaseCommand):
help = 'reinitialize the test user' help = 'reinitialize the test user'
def handle_noargs(self, **options): def handle(self, *args, **options):
user_model = get_user_model() user_model = get_user_model()
try: try:
u = user_model.objects.get(username='test') u = user_model.objects.get(username='test')

View File

@ -247,6 +247,7 @@ ACCOUNT_ACTIVATION_DAYS = 7
REGISTRATION_EMAIL_HTML = False # we override the text, but not the html email template REGISTRATION_EMAIL_HTML = False # we override the text, but not the html email template
LOGIN_REDIRECT_URL = '/overview/' LOGIN_REDIRECT_URL = '/overview/'
LOGOUT_REDIRECT_URL = '/'
X_FRAME_OPTIONS = 'DENY' # for clickjacking middleware X_FRAME_OPTIONS = 'DENY' # for clickjacking middleware
@ -264,8 +265,17 @@ SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_AGE = 14 * 24 * 60 * 60 # 14 days, in seconds (remember_me is True) SESSION_COOKIE_AGE = 14 * 24 * 60 * 60 # 14 days, in seconds (remember_me is True)
SESSION_EXPIRE_AT_BROWSER_CLOSE = True # more safe (remember_me is False) SESSION_EXPIRE_AT_BROWSER_CLOSE = True # more safe (remember_me is False)
# python-social-auth settings # Allow SHA1 for host update secrets
PASSWORD_HASHERS = [
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
'django.contrib.auth.hashers.Argon2PasswordHasher',
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
'django.contrib.auth.hashers.BCryptPasswordHasher',
'django.contrib.auth.hashers.SHA1PasswordHasher',
]
# python-social-auth settings
AUTHENTICATION_BACKENDS = ( AUTHENTICATION_BACKENDS = (
'social_core.backends.amazon.AmazonOAuth2', 'social_core.backends.amazon.AmazonOAuth2',
'social_core.backends.bitbucket.BitbucketOAuth', 'social_core.backends.bitbucket.BitbucketOAuth',

View File

@ -17,7 +17,7 @@
<!-- note: keep jQuery and bootstrap js here, <!-- note: keep jQuery and bootstrap js here,
stuff in the include / block right below might depend on it! stuff in the include / block right below might depend on it!
--> -->
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script> <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
{% include "includes/base_head.html" %} {% include "includes/base_head.html" %}
{% block html_head %}{% endblock %} {% block html_head %}{% endblock %}
@ -58,7 +58,7 @@
<ul class="nav navbar-nav pull-right"> <ul class="nav navbar-nav pull-right">
{% if not request.user.is_authenticated %} {% if not request.user.is_authenticated %}
<li{% if nav_register %} class="active"{% endif %}><a href="{% url 'registration_register' %}"><i class="fa fa-asterisk fa-fw"></i> {% trans "Sign up" %}</a></li> <li{% if nav_register %} class="active"{% endif %}><a href="{% url 'registration_register' %}"><i class="fa fa-asterisk fa-fw"></i> {% trans "Sign up" %}</a></li>
<li{% if nav_login %} class="active"{% endif %}><a href="{% url 'django.contrib.auth.views.login' %}"><i class="fa fa-sign-in fa-fw"></i> {% trans 'Log in' %}</a></li> <li{% if nav_login %} class="active"{% endif %}><a href="{% url 'login' %}"><i class="fa fa-sign-in fa-fw"></i> {% trans 'Log in' %}</a></li>
{% else %} {% else %}
<li class="dropdown"> <li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-user fa-fw"></i> {{ request.user.username }} <b class="caret"></b></a> <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-user fa-fw"></i> {{ request.user.username }} <b class="caret"></b></a>
@ -68,7 +68,7 @@
{% if request.user.is_staff %} {% if request.user.is_staff %}
<li><a href="{% url 'admin:index' %}"><i class="fa fa-wrench fa-fw"></i> {% trans 'Admin interface' %}</a></li> <li><a href="{% url 'admin:index' %}"><i class="fa fa-wrench fa-fw"></i> {% trans 'Admin interface' %}</a></li>
{% endif %} {% endif %}
<li><a href="{% url 'django.contrib.auth.views.logout_then_login' %}"><i class="fa fa-sign-out fa-fw"></i> {% trans 'Log out' %}</a></li> <li><a href="{% url 'logout' %}"><i class="fa fa-sign-out fa-fw"></i> {% trans 'Log out' %}</a></li>
</ul> </ul>
</li> </li>
{% endif %} {% endif %}

View File

@ -3,9 +3,10 @@ top-level url dispatching
""" """
from django.conf import settings from django.conf import settings
from django.conf.urls import patterns, include, url from django.conf.urls import include, url
from django.contrib import admin from django.contrib import admin
from django.contrib.auth import views as auth_views from django.contrib.auth import views as auth_views
from django.conf.urls.static import static
def remember_me_login(request, *args, **kw): def remember_me_login(request, *args, **kw):
@ -20,8 +21,7 @@ def remember_me_login(request, *args, **kw):
return auth_views.login(request, *args, **kw) return auth_views.login(request, *args, **kw)
urlpatterns = patterns( urlpatterns = [
'',
url('', include('social_django.urls', namespace='social')), url('', include('social_django.urls', namespace='social')),
url(r'^accounts/', include('nsupdate.login.urls')), url(r'^accounts/', include('nsupdate.login.urls')),
# registration and user settings # registration and user settings
@ -29,12 +29,9 @@ urlpatterns = patterns(
url(r'^admin/', include(admin.site.urls)), url(r'^admin/', include(admin.site.urls)),
url(r'^i18n/', include('django.conf.urls.i18n')), url(r'^i18n/', include('django.conf.urls.i18n')),
url(r'^', include('nsupdate.main.urls')), url(r'^', include('nsupdate.main.urls')),
) ]
if settings.DEBUG: if settings.DEBUG:
urlpatterns += patterns('django.contrib.staticfiles.views', urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
url(r'^static/(?P<path>.*)$', 'serve'), )
import debug_toolbar import debug_toolbar
urlpatterns += patterns('', urlpatterns += [url(r'^__debug__/', include(debug_toolbar.urls)), ]
url(r'^__debug__/', include(debug_toolbar.urls)),
)

View File

@ -1,7 +1,7 @@
# packages always needed # packages always needed
dnspython dnspython
netaddr netaddr
django>=1.8.1, <1.9 django~=1.11.0
django-bootstrap-form django-bootstrap-form
django-registration-redux django-registration-redux
django-extensions django-extensions

View File

@ -19,6 +19,6 @@ sudo chattr +i /etc/resolv.conf
#dig @127.0.0.1 tests.nsupdate.info SOA #dig @127.0.0.1 tests.nsupdate.info SOA
#sudo netstat -tulpen | grep 53 #sudo netstat -tulpen | grep 53
pip install Django==$DJANGO pip install Django~=$DJANGO
pip install -r requirements.d/travis.txt pip install -r requirements.d/travis.txt
pip install -e . pip install -e .

View File

@ -2,9 +2,6 @@
setup for nsupdate package setup for nsupdate package
""" """
import sys
PY2 = sys.version_info[0] == 2
from setuptools import setup, find_packages from setuptools import setup, find_packages
from nsupdate import version from nsupdate import version
@ -12,11 +9,6 @@ from nsupdate import version
with open('README.rst') as f: with open('README.rst') as f:
readme_content = f.read() readme_content = f.read()
if PY2:
install_requires = ['dnspython', ]
else:
install_requires = ['dnspython3', ]
setup( setup(
name='nsupdate', name='nsupdate',
version=str(version), version=str(version),
@ -53,9 +45,10 @@ setup(
include_package_data=True, include_package_data=True,
zip_safe=False, zip_safe=False,
platforms='any', platforms='any',
install_requires=install_requires + [ install_requires=[
'dnspython',
'netaddr', 'netaddr',
'django>=1.8.1, <1.9', 'django~=1.11.0',
'django-bootstrap-form', 'django-bootstrap-form',
'django-registration-redux', 'django-registration-redux',
'django-extensions', 'django-extensions',