# CCS CS Lab Main Forms # # Douglas Thrift # # $Id$ from ccscslab.main.models import Computer, Person from ccscslab.main.utils import ldap_connection import common from django import forms from django.conf import settings from django.contrib.auth import authenticate from django.contrib.auth.models import User import ldap import re from users import users class LoginForm(forms.Form): person = forms.ModelChoiceField(empty_label = '', label = 'Account', queryset = Person.objects.exclude(name = settings.CCSCSLAB_DEFAULT_PERSON)) password = forms.CharField(max_length = 128, widget = forms.PasswordInput) def clean(self): person = self.cleaned_data.get('person') password = self.cleaned_data.get('password') if person is not None and password is not None: if person.user is None: try: ldap_connection(person.name, password).unbind_s() except ldap.INVALID_CREDENTIALS: raise forms.ValidationError('The password is incorrect.') person.user = User.objects.create_user(person.name, '', password) person.save() while True: user = authenticate(username = person.name, password = password) if user is not None: if user.is_active: self.cleaned_data['user'] = user break else: raise forms.ValidationError('The accound is disabled.') else: try: ldap_connection(person.name, password).unbind_s() except ldap.INVALID_CREDENTIALS: raise forms.ValidationError('The password is incorrect.') user = User.objects.get(username = person.name) user.set_password(password) user.save() return self.cleaned_data class PasswordMixin(object): def clean_password(self): name = self._NAME() password = self.cleaned_data['password'] if name and password == name: raise forms.ValidationError('The password is insecure.') return password def clean_confirm_password(self): password = self.cleaned_data.get('password') confirm_password = self.cleaned_data.get('confirm_password') if password and confirm_password: if password != confirm_password: raise forms.ValidationError("The two password fields didn't match.") return confirm_password class RequestForm(forms.Form, PasswordMixin): name = forms.RegexField(regex = re.compile(r'^[a-z0-9]{1,16}$')) full_name = forms.CharField(max_length = 50) password = forms.CharField(label = 'Temporary Password', max_length = 128, widget = forms.PasswordInput) confirm_password = forms.CharField(label = 'Confirm Password', max_length = 128, widget = forms.PasswordInput) email = forms.EmailField() _NAME = lambda self: self.cleaned_data.get('name') def clean_name(self): name = self.cleaned_data['name'] if name in users or Person.objects.filter(name = name).count(): raise forms.ValidationError('Name is already taken.') return name COMPUTER_CHOICES = [('all', '')] + map(lambda computer: (computer.full_name(), computer.sword), Computer.objects.filter(name__in = map(lambda host: host.split('.', 1)[0], common.HOSTS)).order_by('sword')) class NameForm(forms.Form): computer = forms.ChoiceField(label = 'Computer(s)', choices = COMPUTER_CHOICES) full_name = forms.CharField(max_length = 50) class PasswordForm(forms.Form, PasswordMixin): computer = forms.ChoiceField(label = 'Computer(s)', choices = COMPUTER_CHOICES) action = forms.ChoiceField(label = 'Action', choices = (('change', 'Change'), ('reset', 'Reset'))) old_password = forms.CharField(label = 'Old Password', max_length = 128, required = False, widget = forms.PasswordInput) password = forms.CharField(label = 'New Password', max_length = 128, widget = forms.PasswordInput) confirm_password = forms.CharField(label = 'Confirm Password', max_length = 128, widget = forms.PasswordInput) _NAME = lambda self: self.person.name def __init__(self, user, *args, **kwargs): self.user = user self.person = user.person_set.get() super(PasswordForm, self).__init__(*args, **kwargs) def clean_old_password(self): action = self.cleaned_data['action'] old_password = self.cleaned_data.get('old_password') if action == 'change': if not old_password: raise forms.ValidationError('This field is required.') if not self.user.check_password(old_password): raise forms.ValidationError('Your old password was entered incorrectly. Please enter it again.') return old_password