69 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			69 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """passbook OTP Forms"""
 | |
| 
 | |
| from django import forms
 | |
| from django.contrib.admin.widgets import FilteredSelectMultiple
 | |
| from django.core.validators import RegexValidator
 | |
| from django.utils.safestring import mark_safe
 | |
| from django.utils.translation import ugettext_lazy as _
 | |
| 
 | |
| from passbook.core.forms.factors import GENERAL_FIELDS
 | |
| from passbook.otp.models import OTPFactor
 | |
| 
 | |
| OTP_CODE_VALIDATOR = RegexValidator(r'^[0-9a-z]{6,8}$',
 | |
|                                     _('Only alpha-numeric characters are allowed.'))
 | |
| 
 | |
| 
 | |
| class PictureWidget(forms.widgets.Widget):
 | |
|     """Widget to render value as img-tag"""
 | |
| 
 | |
|     def render(self, name, value, attrs=None, renderer=None):
 | |
|         return mark_safe("<img src=\"%s\" />" % value) # nosec
 | |
| 
 | |
| 
 | |
| class OTPVerifyForm(forms.Form):
 | |
|     """Simple Form to verify OTP Code"""
 | |
|     order = ['code']
 | |
| 
 | |
|     code = forms.CharField(label=_('Code'), validators=[OTP_CODE_VALIDATOR],
 | |
|                            widget=forms.TextInput(attrs={
 | |
|                                'autocomplete': 'off',
 | |
|                                'placeholder': 'Code'
 | |
|                                }))
 | |
| 
 | |
|     def __init__(self, *args, **kwargs):
 | |
|         super().__init__(*args, **kwargs)
 | |
|         # This is a little helper so the field is focused by default
 | |
|         self.fields['code'].widget.attrs.update({'autofocus': 'autofocus'})
 | |
| 
 | |
| 
 | |
| class OTPSetupForm(forms.Form):
 | |
|     """OTP Setup form"""
 | |
|     title = _('Set up OTP')
 | |
|     device = None
 | |
|     qr_code = forms.CharField(widget=PictureWidget, disabled=True, required=False,
 | |
|                               label=_('Scan this Code with your OTP App.'))
 | |
|     code = forms.CharField(label=_('Code'), validators=[OTP_CODE_VALIDATOR],
 | |
|                            widget=forms.TextInput(attrs={'placeholder': _('One-Time Password')}))
 | |
| 
 | |
|     tokens = forms.MultipleChoiceField(disabled=True, required=False)
 | |
| 
 | |
|     def clean_code(self):
 | |
|         """Check code with new otp device"""
 | |
|         if self.device is not None:
 | |
|             if not self.device.verify_token(int(self.cleaned_data.get('code'))):
 | |
|                 raise forms.ValidationError(_("OTP Code does not match"))
 | |
|         return self.cleaned_data.get('code')
 | |
| 
 | |
| class OTPFactorForm(forms.ModelForm):
 | |
|     """Form to edit OTPFactor instances"""
 | |
| 
 | |
|     class Meta:
 | |
| 
 | |
|         model = OTPFactor
 | |
|         fields = GENERAL_FIELDS + ['enforced']
 | |
|         widgets = {
 | |
|             'name': forms.TextInput(),
 | |
|             'order': forms.NumberInput(),
 | |
|             'policies': FilteredSelectMultiple(_('policies'), False)
 | |
|         }
 | 
