python 3.3 port

not much tested yet, be careful
This commit is contained in:
Thomas Waldmann 2013-12-14 00:35:29 +01:00
parent 273c884658
commit 711aba237f
8 changed files with 60 additions and 39 deletions

View File

@ -3,6 +3,7 @@ python:
- "2.6"
- "2.7"
- "pypy"
- "3.3"
env:
global:
- SECRET_KEY=justfortravis

View File

@ -23,25 +23,25 @@ HOSTNAME = 'nsupdate-ddns-client-unittest.' + BASEDOMAIN
def test_myip(client):
response = client.get(reverse('myip'))
assert response.status_code == 200
assert response.content in ['127.0.0.1', '::1']
assert response.content in [b'127.0.0.1', b'::1']
def test_nic_update_noauth(client):
response = client.get(reverse('nic_update'))
assert response.status_code == 401
assert response.content == "badauth"
assert response.content == b'badauth'
def make_basic_auth_header(username, password):
import base64
return "Basic " + base64.b64encode("%s:%s" % (username, password))
return b'Basic ' + base64.b64encode((username + ':' + password).encode('utf-8'))
def test_nic_update_badauth(client):
response = client.get(reverse('nic_update'),
HTTP_AUTHORIZATION=make_basic_auth_header(TEST_HOST, "wrong"))
assert response.status_code == 401
assert response.content == "badauth"
assert response.content == b'badauth'
def test_nic_update_authorized_nonexistent_host(client):
@ -49,7 +49,7 @@ def test_nic_update_authorized_nonexistent_host(client):
HTTP_AUTHORIZATION=make_basic_auth_header(TEST_HOST, TEST_SECRET))
assert response.status_code == 200
# we must not get this updated, it doesn't exist in the database:
assert response.content == 'nohost'
assert response.content == b'nohost'
def test_nic_update_authorized_foreign_host(client):
@ -57,21 +57,21 @@ def test_nic_update_authorized_foreign_host(client):
HTTP_AUTHORIZATION=make_basic_auth_header(TEST_HOST, TEST_SECRET))
assert response.status_code == 200
# we must not get this updated, this is a host of some other user!
assert response.content == 'nohost'
assert response.content == b'nohost'
def test_nic_update_authorized_not_fqdn_hostname(client):
response = client.get(reverse('nic_update') + '?hostname=test',
HTTP_AUTHORIZATION=make_basic_auth_header(TEST_HOST, TEST_SECRET))
assert response.status_code == 200
assert response.content == 'notfqdn'
assert response.content == b'notfqdn'
def test_nic_update_authorized_not_fqdn_username(client):
response = client.get(reverse('nic_update'),
HTTP_AUTHORIZATION=make_basic_auth_header('test', TEST_SECRET))
assert response.status_code == 200
assert response.content == 'notfqdn'
assert response.content == b'notfqdn'
def test_nic_update_authorized(client):
@ -79,7 +79,8 @@ def test_nic_update_authorized(client):
HTTP_AUTHORIZATION=make_basic_auth_header(TEST_HOST, TEST_SECRET))
assert response.status_code == 200
# we don't care whether it is nochg or good, but should be one of them:
assert response.content.startswith('good ') or response.content.startswith('nochg ')
content = response.content.decode('utf-8')
assert content.startswith('good ') or content.startswith('nochg ')
def test_nic_update_authorized_myip(client):
@ -87,17 +88,17 @@ def test_nic_update_authorized_myip(client):
HTTP_AUTHORIZATION=make_basic_auth_header(TEST_HOST, TEST_SECRET))
assert response.status_code == 200
# we don't care whether it is nochg or good, but should be the ip from myip=...:
assert response.content in ['good 4.3.2.1', 'nochg 4.3.2.1']
assert response.content in [b'good 4.3.2.1', b'nochg 4.3.2.1']
response = client.get(reverse('nic_update') + '?myip=1.2.3.4',
HTTP_AUTHORIZATION=make_basic_auth_header(TEST_HOST, TEST_SECRET))
assert response.status_code == 200
# must be good (was different IP)
assert response.content == 'good 1.2.3.4'
assert response.content == b'good 1.2.3.4'
response = client.get(reverse('nic_update') + '?myip=1.2.3.4',
HTTP_AUTHORIZATION=make_basic_auth_header(TEST_HOST, TEST_SECRET))
assert response.status_code == 200
# must be nochg (was same IP)
assert response.content == 'nochg 1.2.3.4'
assert response.content == b'nochg 1.2.3.4'
def test_nic_update_authorized_update_other_services(client):
@ -105,19 +106,19 @@ def test_nic_update_authorized_update_other_services(client):
HTTP_AUTHORIZATION=make_basic_auth_header(TEST_HOST, TEST_SECRET))
assert response.status_code == 200
# we don't care whether it is nochg or good, but should be the ip from myip=...:
assert response.content in ['good 4.3.2.1', 'nochg 4.3.2.1']
assert response.content in [b'good 4.3.2.1', b'nochg 4.3.2.1']
response = client.get(reverse('nic_update') + '?myip=1.2.3.4',
HTTP_AUTHORIZATION=make_basic_auth_header(TEST_HOST, TEST_SECRET))
assert response.status_code == 200
# must be good (was different IP)
assert response.content == 'good 1.2.3.4'
assert response.content == b'good 1.2.3.4'
# now check if it updated the other service also:
assert query_ns(HOSTNAME, 'A') == '1.2.3.4'
response = client.get(reverse('nic_update') + '?myip=2.3.4.5',
HTTP_AUTHORIZATION=make_basic_auth_header(TEST_HOST, TEST_SECRET))
assert response.status_code == 200
# must be good (was different IP)
assert response.content == 'good 2.3.4.5'
assert response.content == b'good 2.3.4.5'
# now check if it updated the other service also:
assert query_ns(HOSTNAME, 'A') == '2.3.4.5'
@ -128,7 +129,7 @@ def test_nic_update_authorized_badagent(client, settings):
HTTP_AUTHORIZATION=make_basic_auth_header(TEST_HOST, TEST_SECRET),
HTTP_USER_AGENT='bad_agent')
assert response.status_code == 200
assert response.content == 'badagent'
assert response.content == b'badagent'
def test_nic_update_session_nosession(client):
@ -140,21 +141,23 @@ def test_nic_update_session_no_hostname(client):
client.login(username=USERNAME, password=PASSWORD)
response = client.get(reverse('nic_update_authorized'))
assert response.status_code == 200
assert response.content == "nohost" # we did not tell which host
assert response.content == b'nohost' # we did not tell which host
def test_nic_update_session(client):
client.login(username=USERNAME, password=PASSWORD)
response = client.get(reverse('nic_update_authorized') + '?hostname=%s' % (TEST_HOST, ))
assert response.status_code == 200
assert response.content.startswith('good ') or response.content.startswith('nochg ')
content = response.content.decode('utf-8')
assert content.startswith('good ') or content.startswith('nochg ')
def test_nic_update_session_myip(client):
client.login(username=USERNAME, password=PASSWORD)
response = client.get(reverse('nic_update_authorized') + '?hostname=%s&myip=%s' % (TEST_HOST, '1.2.3.4'))
assert response.status_code == 200
assert response.content.startswith('good 1.2.3.4') or response.content.startswith('nochg 1.2.3.4')
content = response.content.decode('utf-8')
assert content.startswith('good 1.2.3.4') or content.startswith('nochg 1.2.3.4')
def test_nic_update_session_foreign_host(client):
@ -162,7 +165,7 @@ def test_nic_update_session_foreign_host(client):
response = client.get(reverse('nic_update_authorized') + '?hostname=%s' % TEST_HOST2)
assert response.status_code == 200
# we must not get this updated, this is a host of some other user!
assert response.content == "nohost"
assert response.content == b'nohost'
def test_detect_ip_invalid_session(client):

View File

@ -108,10 +108,12 @@ def basic_authenticate(auth):
:param auth: http basic auth string
:return: username, password
"""
auth = auth.decode('utf-8')
authmeth, auth = auth.split(' ', 1)
if authmeth.lower() != 'basic':
return
auth = auth.strip().decode('base64')
from base64 import b64decode
auth = b64decode(auth.strip()).decode('utf-8')
username, password = auth.split(':', 1)
return username, password

View File

@ -2,6 +2,8 @@
Tests for dnstools module.
"""
from __future__ import print_function
import pytest
pytestmark = pytest.mark.django_db
@ -139,55 +141,55 @@ class TestUpdate(object):
host, ip = TEST_HOST, '1.1.1.1'
remove_records(host)
response = update_ns(host, 'A', ip, action='add', ttl=60)
print response
print(response)
assert query_ns(host, 'A') == ip
response = update_ns(host, 'A', action='del')
print response
print(response)
with pytest.raises(NXDOMAIN):
query_ns(host, 'A') == ip
def test_update_v4(self):
host, ip = TEST_HOST, '2.2.2.2'
response = update_ns(host, 'A', ip, action='upd', ttl=60)
print response
print(response)
assert query_ns(host, 'A') == ip
host, ip = TEST_HOST, '3.3.3.3'
response = update_ns(host, 'A', ip, action='upd', ttl=60)
print response
print(response)
assert query_ns(host, 'A') == ip
def test_add_del_v6(self):
host, ip = TEST_HOST, '::1'
remove_records(host)
response = update_ns(host, 'AAAA', ip, action='add', ttl=60)
print response
print(response)
assert query_ns(host, 'AAAA') == ip
response = update_ns(host, 'AAAA', action='del')
print response
print(response)
with pytest.raises(NXDOMAIN):
query_ns(host, 'AAAA') == ip
def test_update_v6(self):
host, ip = TEST_HOST, '::2'
response = update_ns(host, 'AAAA', ip, action='upd', ttl=60)
print response
print(response)
assert query_ns(host, 'AAAA') == ip
host, ip = TEST_HOST, '::3'
response = update_ns(host, 'AAAA', ip, action='upd', ttl=60)
print response
print(response)
assert query_ns(host, 'AAAA') == ip
def test_update_mixed(self):
host4, ip4 = TEST_HOST, '4.4.4.4'
response = update_ns(host4, 'A', ip4, action='upd', ttl=60)
print response
print(response)
assert query_ns(host4, 'A') == ip4
host6, ip6 = TEST_HOST, '::4'
response = update_ns(host6, 'AAAA', ip6, action='upd', ttl=60)
print response
print(response)
assert query_ns(host6, 'AAAA') == ip6
# make sure the v4 is unchanged
@ -195,7 +197,7 @@ class TestUpdate(object):
host4, ip4 = TEST_HOST, '5.5.5.5'
response = update_ns(host4, 'A', ip4, action='upd', ttl=60)
print response
print(response)
assert query_ns(host4, 'A') == ip4
# make sure the v6 is unchanged
@ -205,4 +207,4 @@ class TestUpdate(object):
# test whether we ONLY can update the TEST_HOST
with pytest.raises(DnsUpdateError):
response = update_ns(INVALID_HOST, 'A', '6.6.6.6', action='upd', ttl=60)
print response
print(response)

View File

@ -2,6 +2,8 @@
Tests for main views module.
"""
from __future__ import print_function
import pytest
from django.core.urlresolvers import reverse
@ -30,7 +32,7 @@ def test_views_anon(client):
# interactive updater shows http basic auth popup
('update', dict(), 401),
]:
print view, kwargs, status_code
print("%s, %s, %s" % (view, kwargs, status_code))
response = client.get(reverse(view, kwargs=kwargs))
assert response.status_code == status_code
@ -53,6 +55,6 @@ def test_views_logged_in(client):
('delete_domain', dict(pk=1), 200),
('update', dict(), 401),
]:
print view, kwargs, status_code
print("%s, %s, %s" % (view, kwargs, status_code))
response = client.get(reverse(view, kwargs=kwargs))
assert response.status_code == status_code

View File

@ -95,7 +95,8 @@ class Domain(models.Model):
algorithm = self.nameserver_update_algorithm
bitlength = UPDATE_ALGORITHMS[algorithm].bitlength
user_model = get_user_model()
secret = user_model.objects.make_random_password(length=bitlength / 8)
secret = user_model.objects.make_random_password(length=bitlength // 8)
secret = secret.encode('utf-8')
self.nameserver_update_secret = secret_base64 = base64.b64encode(secret)
self.save()
return secret_base64

View File

@ -14,7 +14,7 @@ from django.core.urlresolvers import reverse
from django.core.exceptions import PermissionDenied
from django.utils.timezone import now
import dnstools
from . import dnstools
from .forms import (CreateHostForm, EditHostForm, CreateDomainForm, EditDomainForm,
CreateUpdaterHostConfigForm, EditUpdaterHostConfigForm)

View File

@ -2,6 +2,9 @@
setup for nsupdate package
"""
import sys
PY2 = sys.version_info[0] == 2
from setuptools import setup, find_packages
from nsupdate import version
@ -9,6 +12,11 @@ from nsupdate import version
with open('README.rst') as f:
readme_content = f.read()
if PY2:
install_requires = ['dnspython', ]
else:
install_requires = ['dnspython3', ]
setup(
name='nsupdate',
version=str(version),
@ -41,10 +49,9 @@ setup(
include_package_data=True,
zip_safe=False,
platforms='any',
install_requires=[
install_requires=install_requires+[
'django >=1.5.3, <1.7', # 1.5.3 has the session serializer configurable
# 1.7 is not tested yet
'dnspython',
'south',
'django-bootstrap-form',
'django-registration',
@ -65,8 +72,11 @@ setup(
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Topic :: Internet :: Name Service (DNS)',
],
)