from django.http import HttpResponseForbidden
from django.contrib.auth.models import User

# SETUP THE VARS! all comma sep lists
# some vars you should override
allow_ips = '192.168.1.%' # ipaddr list, % is wildcard
allow_users = 'admin' # by username or id num
deny_ips = '%.%.%.%'
deny_users = 'AnonymousUser'
order = 'allow,deny' # either 'allow,deny' 'deny,allow' or any ONE of the choices
# a var you could override
forbid = HttpResponseForbidden("""
    <html>
    <head>
        <title>403 Forbidden</title>
    </head>
    <body>
        <h1>403 Forbidden</h1>
        <p>This resource is unavailable at this time from this computer.</p>
    </body>
    </html>""")
    
splits = lambda x: x.replace(' ','').split(',')
vsplits = lambda x: x.replace('%','').split('.')

def getIP(req):
    ip = req.META['REMOTE_ADDR']
    # forwarded proxy fix for webfaction
    if (not ip or ip == '127.0.0.1') and req.META.has_key('HTTP_X_FORWARDED_FOR'):
        ip = req.META['HTTP_X_FORWARDED_FOR']
    return ip 

def cmpIP(x,y): 
    # Returns boolean whether or not the ip matterns match, % is a wildcard  
    print x,y 
    x = vsplits(x); y = vsplits(y)
    for i in range(4): 
        if x[i] and y[i] and x[i] != y[i]:
            return False
    return True
    
def cmpU(x,y):
    # Do a similar cmp on users
    if x == '%': return True
    u = 'AnonymousUser'
    try: u = User.objects.get(pk=int(x))
    except: 
        try: u = User.objects.get(username=x)
        except: pass
    return u == str(y)
    
def action(xset,yval,mode='ip'):
    # Determine action on a user set and ip set
    print xset,yval,mode
    if mode == 'user':
        for x in xset:
            if x and cmpU(x,yval):
                return True
    elif mode == 'ip':                
        for x in xset:
            if x and cmpIP(x,yval):
                return True
    return False
    
class BanWare(object):
    def process_request(self, request):    
        # gather some info
        user = None
        if hasattr(request, 'user'):
            user = request.user
        elif request.session.has_key('_auth_user_id'):
            user = request.session['_auth_user_id']                 
        ip = getIP(request)

        allow = lambda:  action(splits(allow_users), user, mode='user') or \
             action(splits(allow_ips), ip)
        deny = lambda: action(splits(deny_users), user, mode='user') or \
            action(splits(deny_ips), ip)

        # depending on order, 1 if request is allowed, 0 if its denied
        ra = None
        opts = filter(None,splits(order)[:2])
        print opts
        print allow(),deny()
        if opts:
            for opt in opts:
                if opt=='allow' and allow():
                    ra = 1
                elif opt=='deny' and deny():
                    ra = 0
        else:
            if allow(): ra = 1
            elif deny(): ra = 0
        if not ra:
            # delete sessions when denied
            for k in request.session.keys():
                del request.session[k]
            return forbid
