Merge branch 'master' of github.com:asmaps/nsupdate.info

This commit is contained in:
Arne Schauf 2013-09-29 01:16:09 +02:00
commit b826ea803b
12 changed files with 138 additions and 35 deletions

View File

@ -5,9 +5,12 @@ logger = logging.getLogger(__name__)
from django.http import HttpResponse
from django.conf import settings
from django.contrib.auth.hashers import check_password
from main.forms import *
from main.models import Host
import dns.inet
import os
from main.dnstools import update, SameIpError
@ -21,7 +24,8 @@ def UpdateIpView(request):
af = dns.inet.af_for_address(ipaddr)
key = 'ipv4' if af == dns.inet.AF_INET else 'ipv6'
request.session[key] = ipaddr
return HttpResponse('OK', content_type="text/plain")
image_data = open(settings.STATIC_ROOT+"/1px.gif", "rb").read()
return HttpResponse(image_data, mimetype="image/png")
def basic_challenge(realm, content='Authorization Required'):
@ -61,10 +65,16 @@ def check_auth(username, password):
:param password: update password
:return: True if authenticated, False otherwise.
"""
# in our case username == fqdn
hosts = Host.objects.filter(fqdn=username, update_secret=password)
assert len(hosts) < 2
return bool(hosts)
fqdn = username
hosts = Host.objects.filter(fqdn=fqdn)
num_hosts = len(hosts)
if num_hosts == 0:
return False
if num_hosts > 1:
logging.error("fqdn %s has multiple entries" % fqdn)
return False
password_hash = hosts[0].update_secret
return check_password(password, password_hash)
def Response(content):

View File

@ -27,7 +27,7 @@ def update(fqdn, ipaddr, ttl=60):
current_ipaddr = query_ns(fqdn, rdtype)
# check if ip really changed
ok = ipaddr != current_ipaddr
except dns.resolver.NXDOMAIN:
except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
# no dns entry yet, ok
ok = True
if ok:

View File

@ -0,0 +1,75 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'Host.comment'
db.alter_column(u'main_host', 'comment', self.gf('django.db.models.fields.CharField')(max_length=256, null=True))
# Adding unique constraint on 'Host', fields ['fqdn']
db.create_unique(u'main_host', ['fqdn'])
def backwards(self, orm):
# Removing unique constraint on 'Host', fields ['fqdn']
db.delete_unique(u'main_host', ['fqdn'])
# Changing field 'Host.comment'
db.alter_column(u'main_host', 'comment', self.gf('django.db.models.fields.CharField')(max_length=256))
models = {
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
u'main.host': {
'Meta': {'object_name': 'Host'},
'comment': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '256', 'null': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
'fqdn': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '256'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'last_update': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'update_secret': ('django.db.models.fields.CharField', [], {'max_length': '256'})
}
}
complete_apps = ['main']

View File

@ -5,9 +5,9 @@ from django.forms import ModelForm
class Host(models.Model):
"""TODO: hash update_secret"""
fqdn = models.CharField(max_length=256)
fqdn = models.CharField(max_length=256,unique=True)
update_secret = models.CharField(max_length=256)
comment = models.CharField(max_length=256,default='')
comment = models.CharField(max_length=256,default='',blank=True, null=True)
last_update = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)

View File

@ -4,7 +4,6 @@
{% block content %}
<div class="row">
<div class="col-lg-4">
<h3>Delete Host <small><a href="{% url 'overview' %}"><i class="icon-double-angle-left"></i> back to overview</a></small></h3>
<form action="" method="post">

View File

@ -23,8 +23,8 @@
{% endfor %}
</table>
</div>
<h3>New host</h3>
<div class="col-lg-4">
<div class="col-lg-4">
<h3>New host</h3>
<form method="post" action="">
{% csrf_token %}
{{ form|bootstrap }}
@ -33,13 +33,11 @@
</div>
</div>
<div class="row">
<div class="col-lg-12">
<h3>Information</h3>
<b>your IPv4:</b> <span class="ipv4adr">{{ request.session.ipv4 }}</span> </br>
<b>your IPv6:</b> <span class="ipv6adr">{{ request.session.ipv6 }}</span>
</div>
<div style="display: none">
<img src="//{{ WWW_IPV4_HOST }}/updateip" />
<img src="//{{ WWW_IPV6_HOST }}/updateip" />
</div>
</div>
{% endblock %}

View File

@ -7,8 +7,10 @@ from django.conf import settings
from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.contrib.auth.hashers import make_password
from django.utils.decorators import method_decorator
from django.core.urlresolvers import reverse
import dns.inet
from main.forms import HostForm
from main.models import Host
@ -19,8 +21,11 @@ class HomeView(TemplateView):
def get_context_data(self, *args, **kwargs):
context = super(HomeView, self).get_context_data(*args, **kwargs)
context.update(create_context(self.request))
context['nav_home'] = True
ipaddr = self.request.META['REMOTE_ADDR']
af = dns.inet.af_for_address(ipaddr)
key = 'ipv4' if af == dns.inet.AF_INET else 'ipv6'
self.request.session[key] = ipaddr
return context
@ -39,6 +44,7 @@ class OverviewView(CreateView):
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.created_by = self.request.user
self.object.update_secret = make_password(self.object.update_secret, hasher='sha1')
self.object.save()
messages.add_message(self.request, messages.SUCCESS, 'Host added.')
return HttpResponseRedirect(self.get_success_url())
@ -64,6 +70,7 @@ class HostView(UpdateView):
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.created_by = self.request.user
self.object.update_secret = make_password(self.object.update_secret, hasher='sha1')
self.object.save()
messages.add_message(self.request, messages.SUCCESS, 'Host updated.')
return HttpResponseRedirect(self.get_success_url())

0
nsupdate/manage.py Normal file → Executable file
View File

View File

@ -1,6 +1,7 @@
# Django settings for nsupdate project.
import django.conf.global_settings as DEFAULT_SETTINGS
import dns.tsig
import os
DEBUG = True
TEMPLATE_DEBUG = DEBUG
@ -84,6 +85,10 @@ STATIC_ROOT = ''
# Example: "http://example.com/static/", "http://static.example.com/"
STATIC_URL = '/static/'
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = os.path.join(BASE_DIR, "static")
# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
@ -200,7 +205,7 @@ SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
ACCOUNT_ACTIVATION_DAYS = 7
LOGIN_REDIRECT_URL = '/account/profile/'
LOGIN_REDIRECT_URL = '/overview/'
try:
from .local_settings import *

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -51,15 +51,19 @@
</div>
</div>
<div class="container content wrap">
<div id="message_box">
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ message }}
</div>
{% endfor %}
{% endif %}
<div class="row">
<div class="col-lg-12">
<div id="message_box">
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ message }}
</div>
{% endfor %}
{% endif %}
</div>
</div>
</div>
{% block content %}
<div class="row" style="background-color: #DDDDDD">
@ -67,7 +71,7 @@
<h1><i class="icon-globe icon-4x"></i></h1>
<h3>World wide web</h3>
<p>
nsupdate.info is an <a href="https://github.com/asmaps/nsupdate.info">open-source</a> DynDNS service with IPv4 and IPv6 support.
nsupdate.info is a free and <a href="https://github.com/asmaps/nsupdate.info">open-source</a> dynamic DNS service with IPv4 and IPv6 support.
</p>
</div>
<div class="col-sm-4" style="text-align: center">
@ -88,16 +92,16 @@
<hr>
<div class="row">
<div class="container">
{% if session.ipv4 and session.ipv6 %}
{% if request.session.ipv4 and request.session.ipv6 %}
<p>We think this are your IPs:</p>
{% elif session.ipv4 or session.ipv6 %}
{% elif request.session.ipv4 or request.session.ipv6 %}
<p>We think this is your IP:</p>
{% endif %}
{% if session.ipv4 %}
<h1>{{session.ipv4}}</h1>
{% elif session.ipv6 %}
<h1>{{session.ipv6}}</h1>
{% if request.session.ipv4 %}
<h1>{{request.session.ipv4}}</h1>
{% elif request.session.ipv6 %}
<h1>{{request.session.ipv4}}</h1>
{% else %}
<h1>HeyHo!</h1>
{% endif %}
@ -112,14 +116,19 @@
<p class="text-muted credit">
Sourcecode available at <a href="https://github.com/asmaps/nsupdate.info">GitHub</a>
-
Developed by <a href="https://github.com/asmaps/">Arne Schauf</a>,
developed by <a href="https://github.com/asmaps/">Arne Schauf</a>,
<a href="https://github.com/Samuirai/">Fabian Faessler</a>,
<a href="https://github.com/ThomasWaldmann/">Thomas Waldmann</a>
during the <a href="http://djangodash.com/teams/c4/nsupdateinfo/">Django Dash 2013</a>
during the <a href="http://djangodash.com/teams/c4/nsupdateinfo/">Django Dash 2013</a>.
</p>
</div>
</div>
<div style="display: none">
<img src="//{{ WWW_IPV4_HOST }}/updateip" />
<img src="//{{ WWW_IPV6_HOST }}/updateip" />
</div>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
</body>
</html>