update to django-2, python3, and based on an alpine container

このコミットが含まれているのは:
jeffrey forman 2019-02-13 20:17:05 -05:00
コミット f9176387ac
16個のファイルの変更53行の追加69行の削除

ファイルの表示

@ -1,16 +1,13 @@
FROM python:2.7
FROM python:3-alpine
MAINTAINER Jeffrey Forman <code@jeffreyforman.net>
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /code
COPY . /code/
RUN pip install -r requirements.txt
RUN apk add --no-cache nsd build-base python3-dev libffi-dev openssl-dev libc-dev libxslt-dev \
&& pip install --upgrade pip \
&& pip install --no-cache-dir -r requirements.txt
EXPOSE 8000

ファイルの表示

@ -86,7 +86,6 @@ bootstrapping.
```
python manage.py migrate
python manage.py createsuperuser
...
python manage.py dumpdata -o binder/fixtures/initial_data.json
```

ファイルの表示

@ -1,6 +1,6 @@
import binascii
import dns.tsigkeyring
from models import BindServer, Key
from binder.models import BindServer, Key
from django.contrib import admin
from django.forms import ModelForm, ValidationError

長すぎる行があるためファイル差分は表示されません

ファイルの表示

@ -8,7 +8,7 @@ from django.core import validators
from django.forms import ValidationError
# App Imports
from models import Key
from binder.models import Key
class CustomUnicodeListField(forms.CharField):

ファイルの表示

@ -170,7 +170,7 @@ def ip_info(host_name):
if s_family == 10 and s_type == 1:
ipv6_count += 1
info.append(["IPv6 (%d)" % ipv6_count, s_sockaddr[0]])
except socket.gaierror, err:
except (socket.gaierror, err):
info.append(["Error", "Unable to resolve %s: %s" % (host_name, err)])
return info

ファイルの表示

@ -2,22 +2,26 @@ from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.http import HttpResponseRedirect
class LoginRequiredMiddleware(object):
class LoginRequiredMiddleware:
"""Middleware to redirect to the login page if the user isn't authenticated
After successful authentication the user is redirected back to the page he
initially wanted to access.
"""
def process_request(self, request):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# allow access to the login url
response = self.get_response(request)
if request.path == settings.LOGIN_URL:
return
return response
# redirect to the login url if the user isn't authenticated
if not request.user.is_authenticated():
if not request.user.is_authenticated:
if request.path not in (settings.LOGIN_URL,
settings.LOGIN_REDIRECT_URL):
return HttpResponseRedirect('%s?%s=%s' % (settings.LOGIN_URL,
REDIRECT_FIELD_NAME,
request.path))
else:
return HttpResponseRedirect(settings.LOGIN_URL)
return HttpResponseRedirect(settings.LOGIN_URL)
return response

ファイルの表示

@ -1,11 +1,13 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
# Generated by Django 2.1.5 on 2019-02-12 01:12
from django.db import models, migrations
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
@ -13,32 +15,30 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='BindServer',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('hostname', models.CharField(help_text=b'Host name or IP address of the BIND server.', unique=True, max_length=255)),
('statistics_port', models.IntegerField(help_text=b'Port where the BIND server is serving statistics on.')),
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('hostname', models.CharField(help_text='Host name or IP address of the BIND server.', max_length=255, unique=True)),
('dns_port', models.IntegerField(default=53, help_text='The port where the BIND server is listening for DNS requests. binder especially uses that port for the dynamic zone updates. In most cases you should always leave it at the default port 53.', verbose_name='DNS port')),
('statistics_port', models.IntegerField(help_text='Port where the BIND server is serving statistics on.')),
],
options={
'ordering': ['hostname'],
},
bases=(models.Model,),
),
migrations.CreateModel(
name='Key',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(help_text=b'A human readable name for the key to store, used for further references to the key.', unique=True, max_length=255)),
('data', models.CharField(help_text=b'The private part of the TSIG key.', max_length=255)),
('algorithm', models.CharField(help_text=b'The algorithm which has been used for the key.', max_length=255, choices=[(b'HMAC-MD5.SIG-ALG.REG.INT', b'MD5'), (b'hmac-sha1', b'SHA1'), (b'hmac-sha256', b'SHA256'), (b'hmac-sha384', b'SHA384'), (b'hmac-sha512', b'SHA512')])),
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(help_text='A human readable name for the key to store, used for further references to the key.', max_length=255, unique=True)),
('data', models.CharField(help_text='The private part of the TSIG key.', max_length=255)),
('algorithm', models.CharField(choices=[('HMAC-MD5.SIG-ALG.REG.INT', 'MD5'), ('hmac-sha1', 'SHA1'), ('hmac-sha256', 'SHA256'), ('hmac-sha384', 'SHA384'), ('hmac-sha512', 'SHA512')], help_text='The algorithm which has been used for the key.', max_length=255)),
],
options={
'ordering': ['name'],
},
bases=(models.Model,),
),
migrations.AddField(
model_name='bindserver',
name='default_transfer_key',
field=models.ForeignKey(blank=True, to='binder.Key', help_text=b'The default key to use for all actions with this DNS server as long as no other key is specified explicitly.', null=True),
preserve_default=True,
field=models.ForeignKey(blank=True, help_text='The default key to use for all actions with this DNS server as long as no other key is specified explicitly.', null=True, on_delete=django.db.models.deletion.CASCADE, to='binder.Key'),
),
]

ファイルの表示

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('binder', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='bindserver',
name='dns_port',
field=models.IntegerField(default=53, verbose_name='DNS port', help_text=b'The port where the BIND server is listening for DNSrequests. binder especially uses that port for the dynamic zone updates. In most cases you should always leave it at the default port 53.'),
preserve_default=True,
),
]

ファイルの表示

@ -48,7 +48,7 @@ class Key(models.Model):
def save(self, *args, **kwargs):
f = Fernet(settings.FERNET_KEY)
crypted_key = f.encrypt(bytes(self.data))
crypted_key = f.encrypt(bytes(self.data, encoding="utf8"))
self.data = crypted_key
super(Key, self).save(*args, **kwargs)
@ -59,7 +59,7 @@ class Key(models.Model):
try:
key_data = self.decrypt_keydata()
keyring = dns.tsigkeyring.from_text({self.name: key_data})
except binascii.Error, err:
except (binascii.Error, err):
raise exceptions.KeyringException("Incorrect key data. Verify key: %s. Reason: %s" % (self.name, err))
return keyring
@ -99,6 +99,7 @@ class BindServer(models.Model):
default_transfer_key = models.ForeignKey(Key,
null=True,
blank=True,
on_delete=models.CASCADE,
help_text="The default key to use for all actions "
"with this DNS server as long as no other key is "
"specified explicitly.")
@ -153,7 +154,7 @@ class BindServer(models.Model):
except dns.tsig.PeerBadKey:
# The incorrect TSIG key was selected for transfers.
raise exceptions.TransferException("Unable to list zone records because of a TSIG key mismatch.")
except socket.error, err:
except socket.error as err:
# Thrown when the DNS server does not respond for a zone transfer (XFR).
raise exceptions.TransferException("DNS server did not respond for transfer. Reason: %s" % err)
except dns.exception.FormError:

ファイルの表示

@ -97,13 +97,14 @@ TEMPLATES = [
}
]
MIDDLEWARE_CLASSES = (
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.common.CommonMiddleware',
MIDDLEWARE = (
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'binder.middlewares.LoginRequiredMiddleware',
)

ファイルの表示

@ -54,7 +54,8 @@ class Model_Key_Tests(TestCase):
key_1.save()
decrypt_key = Fernet(settings.FERNET_KEY)
decrypted_tsig_key = decrypt_key.decrypt(bytes(key_1.data))
self.assertEqual(original_tsig_key, decrypted_tsig_key)
self.assertEqual(bytes(original_tsig_key, encoding="utf8"),
decrypted_tsig_key)
@override_settings(FERNET_KEY='yfE1kyYLNlpR-2ybdB-Mvs_k1ZoDMFFVtE_PpWYxVgs=')
def test_FernetKeyDecryptionFailure(self):

ファイルの表示

@ -1,7 +1,7 @@
from django.test import TestCase
from django.test.client import Client
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.urls import reverse
from binder import models
@ -80,7 +80,7 @@ class PostTests(TestCase):
self.assertContains(response,
'<input type="hidden" id="zone_name" name="zone_name" value="testzone1.test.net" />', html=True)
self.assertContains(response,
'<input type="hidden" id="rr_list" name="rr_list" value="[u&#39;testrecord1.testzone1.test.net&#39;, u&#39;testrecord2.testzone1.test.net&#39;]"/>',
'<input type="hidden" id="rr_list" name="rr_list" value="[&#39;testrecord1.testzone1.test.net&#39;, &#39;testrecord2.testzone1.test.net&#39;]"/>',
html=True)
self.assertContains(response,
'<input type="hidden" id="dns_server" name="dns_server" value="testserver.test.net" />',

ファイルの表示

@ -1,14 +1,16 @@
from django.conf.urls import include, url
from django.contrib import admin
import django.contrib.auth.views
from django.contrib.auth import login
from django.contrib.auth.views import logout_then_login
from django.contrib.auth import views as auth_views
import binder.views
admin.autodiscover()
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^admin/', admin.site.urls),
url(r'^accounts/login/$', django.contrib.auth.views.login, name='login'),
url(r'^accounts/logout/$', django.contrib.auth.views.logout_then_login, name='logout'),
url(r'^accounts/login/$', auth_views.LoginView.as_view(), name='login'),
url(r'^accounts/logout/$', logout_then_login, name='logout'),
url(r'^$', binder.views.home_index, name="index"),
url(r'^server_list/$', binder.views.view_server_list, name="server_list"),

ファイルの表示

@ -1,4 +1,4 @@
#!/bin/bash
docker build -t jforman/binder:latest .
docker run -it --rm -v `pwd`:/code/ -w /code/ jforman/binder:latest /bin/bash
docker run -it --rm -v `pwd`:/code/ -w /code/ jforman/binder:latest /bin/ash

ファイルの表示

@ -1,6 +1,5 @@
Django
cryptography
Django>=1.10
dnspython>=1.11
pybindxml>=0.7
lxml
mysqlclient