Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

from captcha.conf import settings as captcha_settings 

from django.db import models 

from django.utils import timezone 

from django.utils.encoding import smart_text 

import datetime 

import random 

import time 

import hashlib 

import logging 

 

 

# Heavily based on session key generation in Django 

# Use the system (hardware-based) random number generator if it exists. 

14 ↛ 17line 14 didn't jump to line 17, because the condition on line 14 was never falseif hasattr(random, 'SystemRandom'): 

randrange = random.SystemRandom().randrange 

else: 

randrange = random.randrange 

MAX_RANDOM_KEY = 18446744073709551616 # 2 << 63 

 

logger = logging.getLogger(__name__) 

 

 

class CaptchaStore(models.Model): 

challenge = models.CharField(blank=False, max_length=32) 

response = models.CharField(blank=False, max_length=32) 

hashkey = models.CharField(blank=False, max_length=40, unique=True) 

expiration = models.DateTimeField(blank=False) 

 

def save(self, *args, **kwargs): 

self.response = self.response.lower() 

if not self.expiration: 

self.expiration = timezone.now() + datetime.timedelta(minutes=int(captcha_settings.CAPTCHA_TIMEOUT)) 

if not self.hashkey: 

key_ = ( 

smart_text(randrange(0, MAX_RANDOM_KEY)) + 

smart_text(time.time()) + 

smart_text(self.challenge, errors='ignore') + 

smart_text(self.response, errors='ignore') 

).encode('utf8') 

self.hashkey = hashlib.sha1(key_).hexdigest() 

del(key_) 

super(CaptchaStore, self).save(*args, **kwargs) 

 

def __unicode__(self): 

return self.challenge 

 

def remove_expired(cls): 

cls.objects.filter(expiration__lte=timezone.now()).delete() 

remove_expired = classmethod(remove_expired) 

 

@classmethod 

def generate_key(cls, generator=None): 

challenge, response = captcha_settings.get_challenge(generator)() 

store = cls.objects.create(challenge=challenge, response=response) 

 

return store.hashkey 

 

@classmethod 

def pick(cls): 

if not captcha_settings.CAPTCHA_GET_FROM_POOL: 

return cls.generate_key() 

 

def fallback(): 

logger.error("Couldn't get a captcha from pool, generating") 

return cls.generate_key() 

 

# Pick up a random item from pool 

minimum_expiration = timezone.now() + datetime.timedelta(minutes=int(captcha_settings.CAPTCHA_GET_FROM_POOL_TIMEOUT)) 

store = cls.objects.filter(expiration__gt=minimum_expiration).order_by('?').first() 

 

return (store and store.hashkey) or fallback() 

 

@classmethod 

def create_pool(cls, count=1000): 

assert count > 0 

while count > 0: 

cls.generate_key() 

count -= 1