VC: Fix error on clone page for legacy-ID events
[cds-indico.git] / indico / modules / auth / forms.py
blob989fcfd218c784f4c9d237b99313ffc20d1beb2f
1 # This file is part of Indico.
2 # Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
4 # Indico is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3 of the
7 # License, or (at your option) any later version.
9 # Indico is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with Indico; if not, see <http://www.gnu.org/licenses/>.
17 from __future__ import unicode_literals
19 from wtforms.fields import StringField, SelectField, PasswordField
20 from wtforms.fields.html5 import EmailField
21 from wtforms.validators import DataRequired, Length, ValidationError, Optional
23 from indico.modules.auth import Identity
24 from indico.modules.users import User
25 from indico.util.i18n import _
26 from indico.web.forms.base import IndicoForm, SyncedInputsMixin
27 from indico.web.forms.validators import ConfirmPassword, used_if_not_synced
28 from indico.web.forms.widgets import SyncedInputWidget
31 def _tolower(s):
32 return s.lower() if s else s
35 def _check_existing_email(form, field):
36 if User.find_all(~User.is_deleted, ~User.is_pending, User.all_emails.contains(field.data)):
37 raise ValidationError(_('This email address is already in use.'))
40 def _check_existing_username(form, field):
41 if Identity.find(provider='indico', identifier=field.data).count():
42 raise ValidationError(_('This username is already in use.'))
45 class LocalLoginForm(IndicoForm):
46 identifier = StringField(_('Username'), [DataRequired()], filters=[_tolower])
47 password = PasswordField(_('Password'), [DataRequired()])
50 class AddLocalIdentityForm(IndicoForm):
51 username = StringField(_('Username'), [DataRequired(), _check_existing_username], filters=[_tolower])
52 password = PasswordField(_('Password'), [DataRequired(), Length(min=5)])
53 confirm_password = PasswordField(_('Confirm password'), [DataRequired(), ConfirmPassword('password')])
56 class EditLocalIdentityForm(IndicoForm):
57 username = StringField(_('Username'), [DataRequired()], filters=[_tolower])
58 password = PasswordField(_('Current password'), [DataRequired()])
59 new_password = PasswordField(_('New password'), [Optional(), Length(min=5)])
60 confirm_new_password = PasswordField(_('Confirm password'), [ConfirmPassword('new_password')])
62 def __init__(self, *args, **kwargs):
63 self.identity = kwargs.pop('identity', None)
64 super(EditLocalIdentityForm, self).__init__(*args, **kwargs)
66 def validate_password(self, field):
67 if field.data != self.identity.password:
68 raise ValidationError(_("Wrong current password"))
70 def validate_username(self, field):
71 query = Identity.find(Identity.provider == 'indico',
72 Identity.identifier == field.data,
73 Identity.identifier != self.identity.identifier)
74 if query.count():
75 raise ValidationError(_('This username is already in use.'))
78 class SelectEmailForm(IndicoForm):
79 email = SelectField(_('Email address'), [DataRequired()],
80 description=_('Choose the email address you want to verify.'))
83 class RegistrationEmailForm(IndicoForm):
84 email = EmailField(_('Email address'), [DataRequired(), _check_existing_email], filters=[_tolower])
87 class RegistrationForm(IndicoForm):
88 first_name = StringField(_('First name'), [DataRequired()])
89 last_name = StringField(_('Family name'), [DataRequired()])
90 affiliation = StringField(_('Affiliation'))
93 class MultipassRegistrationForm(SyncedInputsMixin, IndicoForm):
94 first_name = StringField(_('First Name'), [used_if_not_synced, DataRequired()], widget=SyncedInputWidget())
95 last_name = StringField(_('Family name'), [used_if_not_synced, DataRequired()], widget=SyncedInputWidget())
96 affiliation = StringField(_('Affiliation'), widget=SyncedInputWidget())
97 email = SelectField(_('Email address'), [DataRequired(), _check_existing_email])
98 address = StringField(_('Address'), widget=SyncedInputWidget(textarea=True))
99 phone = StringField(_('Phone number'), widget=SyncedInputWidget())
102 class LocalRegistrationForm(RegistrationForm):
103 email = EmailField(_('Email address'))
104 username = StringField(_('Username'), [DataRequired(), _check_existing_username], filters=[_tolower])
105 password = PasswordField(_('Password'), [DataRequired(), Length(min=5)])
106 confirm_password = PasswordField(_('Confirm password'), [DataRequired(), ConfirmPassword('password')])
109 class ResetPasswordEmailForm(IndicoForm):
110 email = EmailField(_('Email address'), [DataRequired()], filters=[_tolower])
112 def validate_email(self, field):
113 user = self.user
114 if user is None:
115 raise ValidationError(_('There is no profile with this email address.'))
116 elif not user.local_identities:
117 # XXX: Should we allow creating a new identity instead? Would be user-friendly for sure!
118 raise ValidationError(_('This profile has no local account.'))
120 @property
121 def user(self):
122 if not self.is_submitted() or not self.email.data:
123 return None
124 return User.find_first(~User.is_deleted, ~User.is_blocked, ~User.is_pending,
125 User.all_emails.contains(self.email.data))
128 class ResetPasswordForm(IndicoForm):
129 username = StringField(_('Username'))
130 password = PasswordField(_('New password'), [DataRequired(), Length(min=5)])
131 confirm_password = PasswordField(_('Confirm password'), [DataRequired(), ConfirmPassword('password')])