diff --git a/nsupdate/api/views.py b/nsupdate/api/views.py index 0e3a22f..84b3517 100644 --- a/nsupdate/api/views.py +++ b/nsupdate/api/views.py @@ -8,6 +8,7 @@ from django.conf import settings from django.contrib.auth.hashers import check_password from django.contrib.auth.decorators import login_required from django.contrib.sessions.backends.db import SessionStore +from django.utils.timezone import now from ..main.models import Host from ..main.dnstools import update, SameIpError, check_ip @@ -49,6 +50,8 @@ def DetectIpView(request, secret=None): ipaddr = request.META['REMOTE_ADDR'] key = check_ip(ipaddr) s[key] = ipaddr + s[key+'_timestamp'] = now() + logger.debug("detected %s: %s" % (key, ipaddr)) s.save() return HttpResponse(status=204) diff --git a/nsupdate/context_processors.py b/nsupdate/context_processors.py index 086ffb8..390d82a 100644 --- a/nsupdate/context_processors.py +++ b/nsupdate/context_processors.py @@ -1,5 +1,11 @@ # -*- coding: utf-8 -*- + +from datetime import timedelta + from django.conf import settings +from django.utils.timezone import now + +MAX_IP_AGE = 180 # seconds def add_settings(request): @@ -8,3 +14,33 @@ def add_settings(request): context['WWW_IPV4_HOST'] = settings.WWW_IPV4_HOST context['WWW_IPV6_HOST'] = settings.WWW_IPV6_HOST return context + + +def remove_stale_ips(request): + """ + Check the session if there are stale IPs and if so, remove them. + """ + # XXX is a context processor is the right place for this? + s = request.session + t_now = now() + for key in ['ipv4', 'ipv6', ]: + timestamp_key = "%s_timestamp" % key + try: + timestamp = s[timestamp_key] + except KeyError: + pass + else: + try: + stale = timestamp + timedelta(seconds=MAX_IP_AGE) < t_now + except (ValueError, TypeError): + # invalid timestamp in session + del s[timestamp_key] + else: + if stale: + print "ts: %s now: %s - killing %s (was: %s)" % (timestamp, t_now, key, s[key]) + # kill the IP, it is not up-to-date any more + # note: it is used to fill form fields, so set it to empty string + s[key] = '' + # update the timestamp, so we can retry after a while + s[timestamp_key] = t_now + return {} diff --git a/nsupdate/main/templates/main/overview.html b/nsupdate/main/templates/main/overview.html index 9a5d0fc..160ba7b 100644 --- a/nsupdate/main/templates/main/overview.html +++ b/nsupdate/main/templates/main/overview.html @@ -36,8 +36,12 @@

Your current IPs

-

Your IPv4: {{ request.session.ipv4 }}

-

Your IPv6: {{ request.session.ipv6 }}

+ {% if request.session.ipv4 %} +

IPv4: {{ request.session.ipv4 }} (seen {{request.session.ipv4_timestamp|timesince}} ago)

+ {% endif %} + {% if request.session.ipv6 %} +

IPv6: {{ request.session.ipv6 }} (seen {{request.session.ipv6_timestamp|timesince}} ago)

+ {% endif %}

Note: We try to get your IP addresses through a trick, by hosting two fake images:

  1. on a IPv4-only server
  2. diff --git a/nsupdate/settings.py b/nsupdate/settings.py index bde70dc..fd403db 100644 --- a/nsupdate/settings.py +++ b/nsupdate/settings.py @@ -34,6 +34,10 @@ WWW_HOST = BASEDOMAIN WWW_IPV4_HOST = 'ipv4.' + BASEDOMAIN WWW_IPV6_HOST = 'ipv6.' + BASEDOMAIN +# for debugging IP detection on localhost +#WWW_IPV4_HOST = 'localhost:8000' +#WWW_IPV6_HOST = 'ip6-localhost:8000' + BAD_AGENTS = set() # useragent blacklist for /nic/update service # Hosts/domain names that are valid for this site; required if DEBUG is False @@ -119,6 +123,7 @@ MIDDLEWARE_CLASSES = ( TEMPLATE_CONTEXT_PROCESSORS = DEFAULT_SETTINGS.TEMPLATE_CONTEXT_PROCESSORS + ( 'django.core.context_processors.request', 'nsupdate.context_processors.add_settings', + 'nsupdate.context_processors.remove_stale_ips', ) ROOT_URLCONF = 'nsupdate.urls' diff --git a/nsupdate/templates/base.html b/nsupdate/templates/base.html index 9bac7b3..25b447e 100644 --- a/nsupdate/templates/base.html +++ b/nsupdate/templates/base.html @@ -100,15 +100,21 @@
- fake image used for ip v4 address detection - fake image used for ip v6 address detection - + {% if not request.session.ipv4 %} + fake image used for ip v4 address detection + {% endif %} + {% if not request.session.ipv6 %} + fake image used for ip v6 address detection + {% endif %} + {% if not request.session.ipv4 or not request.session.ipv6 %} + + {% endif %}