Source

django-doorkeeper / doorkeeper / views.py

Full commit
# views for django-doorkeeper
# Eugene Gavrish
# 

from django.http import Http404
from models import BotRecord
import datetime, hashlib
from django.conf import settings
from utils import MemClient

import logging
log = logging.getLogger(__name__)

TERM = getattr(settings,'DOORKEEPER_TERM', 1200)
PATIENCE= getattr(settings,'DOORKEEPER_PATIENCE', 5)
MEMCACHE=getattr(settings,'DOORKEEPER_MEMCACHE', False)

def inspect(request):
    """

    View to register suspicious client and raise Http404
    if bad request frequency is higher then PATIENCE
    counter BotRecord.penalty_count increases until threshold.
    Then detention_upto is set to future and middleware begins bouncing
    this client.

    """
    sagent = request.META.get('HTTP_USER_AGENT',"n/a")
    saddr = request.META.get('REMOTE_ADDR',"n/a")
    shash = "%s %s"% (saddr, sagent)
    dd    = hashlib.md5()
    dd.update(shash)
    memhash = dd.hexdigest()

    try:
        if MEMCACHE:
            mc=MemClient(MEMCACHE)
            br=mc.get(memhash)
            
            if br is None:
                br=BotRecord.objects.get(bot_hash=shash)
                mc.add(memhash,br,time=TERM*2)
        else:
            br=BotRecord.objects.get(bot_hash=shash)
        now=datetime.datetime.now()
        delta=datetime.timedelta(0,TERM)
        if br.last_date+delta > now:
            br.penalty_count+=1
            if br.penalty_count > PATIENCE:
                br.detention_upto=now+delta
                br.jail_count+=1
        else:
            if br.penalty_count > PATIENCE:  # for old banned client
                br.penalty_count-=PATIENCE   # forgiving them partly
    except BotRecord.DoesNotExist:
        br=BotRecord.objects.create(bot_hash=shash,bot_name=sagent, bot_adr=saddr)
    br.save()
    if MEMCACHE: 
        mc.set(memhash,br)
        log.error("Memcached view %s, penalty %s, detention %s" % (shash,br.penalty_count,br.detention_upto))
    raise Http404()