wonderbeyond
5/3/2013 - 10:47 AM

A django view decorator that limits access in specified IP areas.

A django view decorator that limits access in specified IP areas.

def ip_in_expected_networks(ip, networks):
    '''
    check if an ip in listed networks

    >>> ip_in_expected_networks('10.234.99.179', ['192.168.0.22/24', '10.234.99.0/24'])
    True
    >>> ip_in_expected_networks('10.234.99.179', ['10.234.99.179'])
    True
    >>> ip_in_expected_networks('10.234.0.179', ['10.234.99.179/24'])
    False
    >>> ip_in_expected_networks('', ['10.234.99.179/24'])
    False
    '''
    import ipaddr

    if not ip or not networks:
        return False

    ip = ipaddr.IPAddress(ip)
    for network in networks:
        if ip in ipaddr.IPNetwork(network):
            return True
    return False
from django.http import HttpResponse, HttpResponseForbidden
from django.conf import settings
from functools import wraps
from django.utils.decorators import available_attrs
from utils import ip_in_expected_networks

def limit_access_by_ip(allowed_ips=settings.INTERNAL_IPS):
    '''Decorator to limit access in specified  IP areas.'''
    def decorator(view_func):
        @wraps(view_func, assigned=available_attrs(view_func))
        def _view(request, *args, **kwargs):
            if ip_in_expected_networks(request.META.get('REMOTE_ADDR'), allowed_ips):
                return view_func(request, *args, **kwargs)
            else:
                return HttpResponseForbidden('Forbidden')
        return _view
    return decorator