Coverage for /Users/marco/Code/django-simple-captcha/captcha/fields.py: 86.79%

# Coverage for /Users/marco/Code/django-simple-captcha/captcha/fields.py : 86.79%

## 117 statements 107 run 10 missing 0 excluded 9 partial

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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | from captcha.conf import settings from captcha.models import CaptchaStore import django from django.core.exceptions import ImproperlyConfigured 5 ↛ 6line 5 didn't jump to line 6, because the condition on line 5 was never trueif django.VERSION < (1, 10): # NOQA from django.core.urlresolvers import reverse, NoReverseMatch # NOQA else: # NOQA from django.urls import reverse, NoReverseMatch # NOQA from django.forms import ValidationError from django.forms.fields import CharField, MultiValueField from django.forms.widgets import TextInput, MultiWidget, HiddenInput from django.utils.translation import ugettext_lazy from django.utils import timezone from django.template.loader import render_to_string from django.utils.safestring import mark_safe from six import u class BaseCaptchaTextInput(MultiWidget): """ Base class for Captcha widgets """ def __init__(self, attrs=None): widgets = ( HiddenInput(attrs), TextInput(attrs), ) super(BaseCaptchaTextInput, self).__init__(widgets, attrs) def decompress(self, value): if value: return value.split(',') return [None, None] def fetch_captcha_store(self, name, value, attrs=None, generator=None): """ Fetches a new CaptchaStore This has to be called inside render """ try: reverse('captcha-image', args=('dummy',)) except NoReverseMatch: raise ImproperlyConfigured('Make sure you\'ve included captcha.urls as explained in the INSTALLATION section on http://readthedocs.org/docs/django-simple-captcha/en/latest/usage.html#installation') 45 ↛ 46line 45 didn't jump to line 46, because the condition on line 45 was never true if settings.CAPTCHA_GET_FROM_POOL: key = CaptchaStore.pick() else: key = CaptchaStore.generate_key(generator) # these can be used by format_output and render self._value = [key, u('')] self._key = key self.id_ = self.build_attrs(attrs).get('id', None) def id_for_label(self, id_): 56 ↛ 58line 56 didn't jump to line 58, because the condition on line 56 was never false if id_: return id_ + '_1' return id_ def image_url(self): return reverse('captcha-image', kwargs={'key': self._key}) def audio_url(self): return reverse('captcha-audio', kwargs={'key': self._key}) if settings.CAPTCHA_FLITE_PATH else None def refresh_url(self): return reverse('captcha-refresh') class CaptchaTextInput(BaseCaptchaTextInput): def __init__(self, attrs=None, **kwargs): self._args = kwargs self._args['output_format'] = self._args.get('output_format') or settings.CAPTCHA_OUTPUT_FORMAT self._args['field_template'] = self._args.get('field_template') or settings.CAPTCHA_FIELD_TEMPLATE # self._args['id_prefix'] = self._args.get('id_prefix') 77 ↛ 78line 77 didn't jump to line 78, because the condition on line 77 was never true if self._args['output_format'] is None and self._args['field_template'] is None: raise ImproperlyConfigured('You MUST define either CAPTCHA_FIELD_TEMPLATE or CAPTCHA_OUTPUT_FORMAT setting. Please refer to http://readthedocs.org/docs/django-simple-captcha/en/latest/usage.html#installation') if self._args['output_format']: for key in ('image', 'hidden_field', 'text_field'): if '%%(%s)s' % key not in self._args['output_format']: raise ImproperlyConfigured('All of %s must be present in your CAPTCHA_OUTPUT_FORMAT setting. Could not find %s' % ( ', '.join(['%%(%s)s' % k for k in ('image', 'hidden_field', 'text_field')]), '%%(%s)s' % key )) super(CaptchaTextInput, self).__init__(attrs) def build_attrs(self, *args, **kwargs): ret = super(CaptchaTextInput, self).build_attrs(*args, **kwargs) if self._args.get('id_prefix') and 'id' in ret: ret['id'] = '%s_%s' % (self._args.get('id_prefix'), ret['id']) return ret def id_for_label(self, id_): ret = super(CaptchaTextInput, self).id_for_label(id_) if self._args.get('id_prefix') and 'id' in ret: ret = '%s_%s' % (self._args.get('id_prefix'), ret) return ret def format_output(self, rendered_widgets): # hidden_field, text_field = rendered_widgets if self._args['output_format']: ret = self._args['output_format'] % { 'image': self.image_and_audio, 'hidden_field': self.hidden_field, 'text_field': self.text_field } return ret 112 ↛ exitline 112 didn't return from function 'format_output', because the condition on line 112 was never false elif self._args['field_template']: context = { 'image': mark_safe(self.image_and_audio), 'hidden_field': mark_safe(self.hidden_field), 'text_field': mark_safe(self.text_field) } return render_to_string(settings.CAPTCHA_FIELD_TEMPLATE, context) def render(self, name, value, attrs=None, renderer=None): self.fetch_captcha_store(name, value, attrs, self._args.get('generator')) context = { 'image': self.image_url(), 'name': name, 'key': self._key, 'id': u'%s_%s' % (self._args.get('id_prefix'), attrs.get('id')) if self._args.get('id_prefix') else attrs.get('id') } 129 ↛ 132line 129 didn't jump to line 132, because the condition on line 129 was never false if settings.CAPTCHA_FLITE_PATH: context.update({'audio': self.audio_url()}) self.image_and_audio = render_to_string(settings.CAPTCHA_IMAGE_TEMPLATE, context) self.hidden_field = render_to_string(settings.CAPTCHA_HIDDEN_FIELD_TEMPLATE, context) self.text_field = render_to_string(settings.CAPTCHA_TEXT_FIELD_TEMPLATE, context) extra_kwargs = {} 137 ↛ 141line 137 didn't jump to line 141, because the condition on line 137 was never false if django.VERSION >= (1, 11): # https://docs.djangoproject.com/en/1.11/ref/forms/widgets/#django.forms.Widget.render extra_kwargs['renderer'] = renderer return super(CaptchaTextInput, self).render(name, self._value, attrs=attrs, **extra_kwargs) def _render(self, template_name, context, renderer=None): return self.format_output(None) class CaptchaField(MultiValueField): def __init__(self, *args, **kwargs): fields = ( CharField(show_hidden_initial=True), CharField(), ) if 'error_messages' not in kwargs or 'invalid' not in kwargs.get('error_messages'): 154 ↛ 156line 154 didn't jump to line 156, because the condition on line 154 was never false if 'error_messages' not in kwargs: kwargs['error_messages'] = {} kwargs['error_messages'].update({'invalid': ugettext_lazy('Invalid CAPTCHA')}) kwargs['widget'] = kwargs.pop('widget', CaptchaTextInput( output_format=kwargs.pop('output_format', None), id_prefix=kwargs.pop('id_prefix', None), generator=kwargs.pop('generator', None) )) super(CaptchaField, self).__init__(fields, *args, **kwargs) def compress(self, data_list): if data_list: return ','.join(data_list) return None def clean(self, value): super(CaptchaField, self).clean(value) response, value[1] = (value[1] or '').strip().lower(), '' 174 ↛ 176line 174 didn't jump to line 176, because the condition on line 174 was never false if not settings.CAPTCHA_GET_FROM_POOL: CaptchaStore.remove_expired() if settings.CAPTCHA_TEST_MODE and response.lower() == 'passed': # automatically pass the test try: # try to delete the captcha based on its hash CaptchaStore.objects.get(hashkey=value[0]).delete() except CaptchaStore.DoesNotExist: # ignore errors pass elif not self.required and not response: pass else: try: CaptchaStore.objects.get(response=response, hashkey=value[0], expiration__gt=timezone.now()).delete() except CaptchaStore.DoesNotExist: raise ValidationError(getattr(self, 'error_messages', {}).get('invalid', ugettext_lazy('Invalid CAPTCHA'))) return value