class OrganisationCountryAdminForm(OrganisationEmailAdminForm): """ A form for a country admin for update organisations """ # use the ModelChoiceField, because organisation_country is a ChainedForeignKey and we don't display the # association organisation_country = ModelChoiceField( queryset=OrganisationCountry.objects.none(), required=True, label=_("Country"), widget=bootstrap.Select2()) class Meta(OrganisationBaseForm.Meta): fields = OrganisationBaseForm.Meta.fields + ( 'organisation_country', 'admin_region', 'name', 'center_type', 'is_active') # , 'can_publish') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) assignable_countries = self.user.get_assignable_organisation_countries( ) self.fields['organisation_country'].queryset = assignable_countries if not AdminRegion.objects.filter( organisation_country__in=assignable_countries).exists(): del self.fields['admin_region'] def clean(self): cleaned_data = super().clean() self.instance.association = cleaned_data[ 'organisation_country'].association return cleaned_data
class Meta: model = AdminRegion fields = ('name', 'homepage', 'organisation_country', 'is_active') widgets = { 'homepage': bootstrap.TextInput(attrs={'size': 50}), 'organisation_country': bootstrap.Select2(), 'name': bootstrap.TextInput(attrs={'size': 50}), }
class OrganisationRegionAdminForm(OrganisationEmailAdminForm): """ A form for a regional admin """ # don't use the default ModelChoiceField, because the regions are restricted to the # administrable_organisation_regions of the region admin organisation_country = ModelChoiceField( queryset=OrganisationCountry.objects.none(), required=True, label=_("Country"), widget=bootstrap.Select2()) admin_region = ModelChoiceField(queryset=AdminRegion.objects.none(), required=True, label=_("Admin Region"), widget=bootstrap.Select2()) class Meta(OrganisationBaseForm.Meta): fields = OrganisationBaseForm.Meta.fields + ( 'organisation_country', 'admin_region', 'name', 'center_type', 'is_active') # , 'can_publish') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) regions = self.user.get_assignable_organisation_regions() self.fields['admin_region'].queryset = regions self.fields[ 'organisation_country'].queryset = OrganisationCountry.objects.filter( adminregion__in=regions, association__is_external=False).distinct() def clean(self): """ check if the admin_region and country fits together """ cleaned_data = super().clean() admin_region = cleaned_data['admin_region'] organisation_country = cleaned_data['organisation_country'] if admin_region.organisation_country != organisation_country: msg = _("The admin region is not valid for the selected country.") raise ValidationError(msg) self.instance.association = cleaned_data[ 'organisation_country'].association return cleaned_data
class Meta: model = OrganisationCountry fields = ('association', 'homepage', 'country_groups', 'country', 'is_active') widgets = { 'homepage': bootstrap.TextInput(attrs={'size': 50}), 'association': bootstrap.Select(), 'country': bootstrap.Select2(), }
class Meta: model = Organisation fields = ('name_native', 'homepage', 'source_urls', 'google_plus_page', 'facebook_page', 'twitter_page', 'founded', 'coordinates_type', 'is_private', 'is_live', 'location', 'neighbour_distance', 'transregional_distance', 'timezone') years_to_display = range(datetime.datetime.now().year - 100, datetime.datetime.now().year + 1) widgets = { 'homepage': bootstrap.URLInput(attrs={'size': 50}), 'source_urls': bootstrap.Textarea(attrs={'rows': '3'}), 'google_plus_page': bootstrap.URLInput(attrs={'size': 50}), 'facebook_page': bootstrap.URLInput(attrs={'size': 50}), 'twitter_page': bootstrap.URLInput(attrs={'size': 50}), 'association': bootstrap.Select(), 'name': bootstrap.TextInput(attrs={'size': 50}), 'name_native': bootstrap.TextInput(attrs={'size': 50}), 'founded': bootstrap.SelectDateWidget(years=years_to_display), 'coordinates_type': bootstrap.Select(), 'center_type': bootstrap.Select(), 'is_private': bootstrap.CheckboxInput(), 'is_active': bootstrap.CheckboxInput(), 'is_live': bootstrap.CheckboxInput(), 'timezone': bootstrap.Select2(), 'location': bootstrap.OSMWidget(), 'neighbour_distance': bootstrap.TextInput(attrs={ 'type': 'number', 'step': '0.001' }), 'transregional_distance': bootstrap.TextInput(attrs={ 'type': 'number', 'step': '0.001' }), }
class AccessRequestForm(BaseForm): message = forms.CharField(label=_("Message"), widget=bootstrap.Textarea(attrs={ 'cols': 40, 'rows': 5 })) picture = Base64ImageField(label=_('Your picture'), required=True, help_text=_('Please use a photo of your face.'), widget=bootstrap.ClearableBase64ImageWidget( attrs={ 'max_file_size': User.MAX_PICTURE_SIZE, 'width': User.PICTURE_WIDTH, 'height': User.PICTURE_HEIGHT, })) created = forms.BooleanField(widget=forms.HiddenInput(), required=False) organisation = forms.ModelChoiceField(queryset=Organisation.objects.filter( is_active=True, is_selectable=True, association__is_selectable=True).only( 'id', 'location', 'name', 'organisation_country__country__iso2_code', 'association__name').prefetch_related( 'organisation_country__country', 'association'), label=_("Organisation"), widget=bootstrap.Select2()) class Meta: model = AccessRequest fields = ('message', 'application', 'user', 'picture', 'organisation') widgets = { 'message': bootstrap.Textarea(), 'application': forms.HiddenInput(), 'user': forms.HiddenInput() } def __init__(self, initial=None, instance=None, *args, **kwargs): user = kwargs.pop('user') # remove custom user keyword super().__init__(initial=initial, instance=instance, *args, **kwargs) if user.picture: del self.fields['picture'] if user.organisations.all(): del self.fields['organisation'] def save(self, commit=True): cd = self.cleaned_data if 'picture' in cd: self.instance.user.picture = cd.get('picture') self.instance.user.save() return super().save(commit)
class Meta: model = UserAddress fields = ('primary', 'address_type', 'addressee', 'street_address', 'city', 'city_native', 'postal_code', 'country', 'region') widgets = { 'primary': bootstrap.CheckboxInput(), 'address_type': bootstrap.Select(), 'addressee': bootstrap.TextInput(attrs={'size': 50}), 'street_address': bootstrap.Textarea(attrs={ 'cols': 50, 'rows': 2 }), 'city': bootstrap.TextInput(attrs={'size': 50}), 'city_native': bootstrap.TextInput(attrs={'size': 50}), 'postal_code': bootstrap.TextInput(attrs={'size': 50}), 'country': bootstrap.Select2(), 'region': bootstrap.TextInput(attrs={'size': 50}), }
class OrganisationAddressForm(BaseForm): # Select2 does not work with StackedInlineForm country = ModelChoiceField(queryset=Country.objects.filter(active=True), required=True, label=_("Country"), widget=bootstrap.Select2(), to_field_name="iso2_code") class Meta: model = OrganisationAddress fields = ('address_type', 'addressee', 'careof', 'street_address', 'city', 'city_native', 'postal_code', 'country', 'region') widgets = { 'address_type': bootstrap.Select(attrs={'class': 'address_type'}), 'addressee': bootstrap.TextInput(attrs={'size': 50}), 'careof': bootstrap.TextInput(attrs={'size': 50}), 'street_address': bootstrap.Textarea(attrs={ 'cols': 50, 'rows': 2 }), 'city': bootstrap.TextInput(attrs={'size': 50}), 'city_native': bootstrap.TextInput(attrs={'size': 50}), 'postal_code': bootstrap.TextInput(attrs={'size': 50}), 'region': bootstrap.TextInput(attrs={'size': 50}), } def __init__(self, *args, **kwargs): instance = kwargs.get('instance') if instance and instance.country: # update initial field because of to_field_name in ModelChoiceField kwargs['initial'] = {'country': instance.country.iso2_code} super().__init__(*args, **kwargs) def template(self): return 'organisations/addresses.html'
class UserAddForm(mixins.UserRolesMixin, mixins.UserNoteMixin, forms.ModelForm): """ form for SSO User Admins for adding users in the frontend """ email = forms.EmailField(label=_('Email'), required=True, widget=bootstrap.EmailInput()) first_name = forms.CharField( label=_('First name'), required=True, widget=bootstrap.TextInput( attrs={'placeholder': capfirst(_('first name'))})) last_name = forms.CharField( label=_('Last name'), required=True, widget=bootstrap.TextInput( attrs={'placeholder': capfirst(_('last name'))})) gender = forms.ChoiceField(label=_('Gender'), required=True, choices=(BLANK_CHOICE_DASH + User.GENDER_CHOICES), widget=bootstrap.Select()) dob = forms.DateField(label=_('Date of birth'), required=False, widget=bootstrap.SelectDateWidget( years=range(datetime.datetime.now().year - 100, datetime.datetime.now().year + 1))) notes = forms.CharField(label=_("Notes"), required=False, max_length=1024, widget=bootstrap.Textarea(attrs={ 'cols': 40, 'rows': 10 })) organisations = forms.ModelChoiceField( queryset=None, required=settings.SSO_ORGANISATION_REQUIRED, label=_("Organisation"), widget=bootstrap.Select2()) application_roles = forms.ModelMultipleChoiceField( queryset=None, required=False, widget=bootstrap.FilteredSelectMultiple(_("Application roles")), label=_("Additional application roles"), help_text=mixins.UserRolesMixin.application_roles_help) role_profiles = forms.ModelMultipleChoiceField( queryset=None, required=False, widget=bootstrap.CheckboxSelectMultiple(), label=_("Role profiles"), help_text=mixins.UserRolesMixin.role_profiles_help) error_messages = { 'duplicate_email': _("A user with that email address already exists."), } class Meta: model = User fields = ("first_name", "last_name", 'gender', 'dob', 'notes', 'application_roles', 'role_profiles') def __init__(self, request, *args, **kwargs): self.request = request user = request.user super().__init__(*args, **kwargs) self.fields[ 'application_roles'].queryset = user.get_administrable_application_roles( ) self.fields[ 'role_profiles'].queryset = user.get_administrable_role_profiles() self.fields['organisations'].queryset = user.get_administrable_user_organisations(). \ filter(is_active=True, association__is_selectable=True) if not user.has_perm("accounts.access_all_users"): self.fields['organisations'].required = True def clean_email(self): # Check if email is unique, email = self.cleaned_data["email"] try: User.objects.get_by_email(email) raise forms.ValidationError(self.error_messages['duplicate_email']) except ObjectDoesNotExist: pass return email def save(self, commit=True): user = super().save(commit=False) user.set_password(get_random_string(40)) user.username = default_username_generator( capfirst(self.cleaned_data.get('first_name')), capfirst(self.cleaned_data.get('last_name'))) organisation = self.cleaned_data["organisations"] if is_validation_period_active(organisation): user.valid_until = now() + datetime.timedelta( days=settings.SSO_VALIDATION_PERIOD_DAYS) user.save() # use mixin to send notification self.user = user current_user = self.request.user self.update_user_m2m_fields('organisations', current_user) self.update_user_m2m_fields('application_roles', current_user) self.update_user_m2m_fields('role_profiles', current_user) self.create_note_if_required(current_user, self.cleaned_data) user.create_primary_email(email=self.cleaned_data["email"]) return user
class RegistrationProfileForm(mixins.UserRolesMixin, forms.Form): """ Form for organisation and region admins """ error_messages = { 'duplicate_username': _("A user with that username already exists."), 'duplicate_email': _("A user with that email address already exists."), } username = forms.CharField(label=_("Username"), max_length=30, widget=bootstrap.TextInput()) notes = forms.CharField(label=_("Notes"), required=False, max_length=1024, widget=bootstrap.Textarea(attrs={ 'cols': 40, 'rows': 10 })) first_name = forms.CharField(label=_('First name'), max_length=30, widget=bootstrap.TextInput()) last_name = forms.CharField(label=_('Last name'), max_length=30, widget=bootstrap.TextInput()) email = forms.EmailField( label=_('Email address'), required=False, widget=bootstrap.TextInput(attrs={'disabled': ''})) date_registered = bootstrap.ReadOnlyField(label=_("Date registered")) country = bootstrap.ReadOnlyField(label=_("Country")) city = bootstrap.ReadOnlyField(label=_("City")) language = bootstrap.ReadOnlyField(label=_("Language")) timezone = bootstrap.ReadOnlyField(label=_("Timezone")) gender = forms.ChoiceField(label=_('Gender'), required=False, choices=(BLANK_CHOICE_DASH + User.GENDER_CHOICES), widget=bootstrap.Select()) dob = forms.CharField(label=_("Date of birth"), required=False, widget=bootstrap.TextInput(attrs={'disabled': ''})) about_me = forms.CharField(label=_('About me'), required=False, widget=bootstrap.Textarea(attrs={ 'cols': 40, 'rows': 5, 'readonly': 'readonly' })) known_person1_first_name = forms.CharField(label=_("First name"), max_length=100, required=False, widget=bootstrap.TextInput()) known_person1_last_name = forms.CharField(label=_("Last name"), max_length=100, required=False, widget=bootstrap.TextInput()) known_person2_first_name = forms.CharField(label=_("First name"), max_length=100, required=False, widget=bootstrap.TextInput()) known_person2_last_name = forms.CharField(label=_("Last name"), max_length=100, required=False, widget=bootstrap.TextInput()) last_modified_by_user = forms.CharField( label=_("Last modified by"), required=False, widget=bootstrap.TextInput(attrs={'disabled': ''})) organisations = forms.ModelChoiceField( queryset=None, label=_("Organisation"), widget=bootstrap.Select2(), required=settings.SSO_ORGANISATION_REQUIRED) application_roles = forms.ModelMultipleChoiceField( queryset=None, required=False, widget=bootstrap.FilteredSelectMultiple(_("Application roles")), label=_("Additional application roles"), help_text=mixins.UserRolesMixin.application_roles_help) check_back = forms.BooleanField( label=_("Check back"), help_text=_('Designates if there are open questions to check.'), required=False, disabled=True) is_access_denied = forms.BooleanField( label=_("Access denied"), help_text=_('Designates if access is denied to the user.'), required=False, disabled=True) is_stored_permanently = forms.BooleanField( label=_("Store permanantly"), help_text=_( 'Keep stored in database to prevent re-registration of denied user.' ), required=False) role_profiles = forms.MultipleChoiceField( required=False, widget=bootstrap.CheckboxSelectMultiple(), label=_("Role profiles"), help_text=mixins.UserRolesMixin.role_profiles_help) def clean_username(self): username = self.cleaned_data["username"] try: get_user_model().objects.exclude(pk=self.user.pk).get( username=username) except ObjectDoesNotExist: return username raise forms.ValidationError(self.error_messages['duplicate_username']) def __init__(self, *args, **kwargs): self.request = kwargs.pop('request') self.registrationprofile = kwargs.pop('instance') self.user = self.registrationprofile.user registrationprofile_data = model_to_dict(self.registrationprofile) user_data = model_to_dict(self.user) if self.user.language: user_data['language'] = self.user.get_language_display() try: # after registration, the user should have exactly 1 center user_data['organisations'] = self.user.organisations.first() except ObjectDoesNotExist: # center is optional # logger.error("User without center?", exc_info=1) pass # initialize form correctly user_data['role_profiles'] = [ str(role_profile.id) for role_profile in self.user.role_profiles.all() ] address_data = {} if self.user.useraddress_set.exists(): useraddress = self.user.useraddress_set.first() address_data = model_to_dict(useraddress) address_data['country'] = useraddress.country initial = kwargs.get('initial', {}) initial.update(registrationprofile_data) initial.update(user_data) initial.update(address_data) initial['email'] = self.user.primary_email() last_modified_by_user = self.registrationprofile.last_modified_by_user initial[ 'last_modified_by_user'] = last_modified_by_user if last_modified_by_user else '' kwargs['initial'] = initial super().__init__(*args, **kwargs) current_user = self.request.user self.fields[ 'application_roles'].queryset = current_user.get_administrable_application_roles( ) # self.fields['role_profiles'].queryset = current_user.get_administrable_role_profiles() self.fields['role_profiles'].choices = [ (role_profile.id, role_profile) for role_profile in current_user.get_administrable_role_profiles() ] self.fields[ 'organisations'].queryset = current_user.get_administrable_user_organisations( ) def save(self): cd = self.cleaned_data current_user = self.request.user # registrationprofile data self.registrationprofile.known_person1_first_name = cd[ 'known_person1_first_name'] self.registrationprofile.known_person1_last_name = cd[ 'known_person1_last_name'] self.registrationprofile.known_person2_first_name = cd[ 'known_person2_first_name'] self.registrationprofile.known_person2_last_name = cd[ 'known_person2_last_name'] self.registrationprofile.save() # user data self.user.username = cd['username'] self.user.first_name = cd['first_name'] self.user.last_name = cd['last_name'] self.user.is_stored_permanently = cd['is_stored_permanently'] if cd['notes']: UserNote.objects.create_note(user=self.user, notes=[cd['notes']], created_by_user=current_user) # userprofile data self.update_user_m2m_fields('organisations', current_user) self.update_user_m2m_fields('application_roles', current_user) self.update_user_m2m_fields('role_profiles', current_user) organisation = self.cleaned_data['organisations'] if is_validation_period_active(organisation): # a new registered user is valid_until from now for the validation period self.user.valid_until = now() + datetime.timedelta( days=settings.SSO_VALIDATION_PERIOD_DAYS) self.user.save() return self.registrationprofile
class UserSelfRegistrationForm(forms.Form): """ used in for the user self registration """ error_messages = { 'duplicate_username': _("A user with that username already exists."), 'duplicate_email': _("A user with that email address already exists."), } first_name = forms.CharField( label=_('First name'), required=True, max_length=30, widget=bootstrap.TextInput( attrs={'placeholder': capfirst(_('first name'))})) last_name = forms.CharField( label=_('Last name'), required=True, max_length=30, widget=bootstrap.TextInput( attrs={'placeholder': capfirst(_('last name'))})) email = forms.EmailField(label=_('Email'), required=True, widget=bootstrap.EmailInput()) picture = Base64ImageField( label=_('Your picture'), help_text= _('Please use a photo of your face. We are using it also to validate your registration.' ), widget=bootstrap.ClearableBase64ImageWidget( attrs={ 'max_file_size': User.MAX_PICTURE_SIZE, 'width': User.PICTURE_WIDTH, 'height': User.PICTURE_HEIGHT, })) known_person1_first_name = forms.CharField(label=_("First name"), max_length=100, widget=bootstrap.TextInput()) known_person1_last_name = forms.CharField(label=_("Last name"), max_length=100, widget=bootstrap.TextInput()) known_person2_first_name = forms.CharField(label=_("First name"), max_length=100, widget=bootstrap.TextInput()) known_person2_last_name = forms.CharField(label=_("Last name"), max_length=100, widget=bootstrap.TextInput()) about_me = forms.CharField( label=_('About me'), required=False, help_text= _('If you would like to tell us something about yourself, please do so in this box.' ), widget=bootstrap.Textarea(attrs={ 'cols': 40, 'rows': 5 })) country = forms.ModelChoiceField( queryset=Country.objects.filter(active=True), label=_("Country"), widget=bootstrap.Select2()) city = forms.CharField(label=_("City"), max_length=100, widget=bootstrap.TextInput()) language = forms.ChoiceField( label=_("Language"), required=False, choices=(BLANK_CHOICE_DASH + sorted(list(settings.LANGUAGES), key=lambda x: x[1])), widget=bootstrap.Select2()) timezone = forms.ChoiceField( label=_("Timezone"), required=False, choices=BLANK_CHOICE_DASH + list(zip(pytz.common_timezones, pytz.common_timezones)), widget=bootstrap.Select2()) gender = forms.ChoiceField(label=_('Gender'), required=False, choices=(BLANK_CHOICE_DASH + User.GENDER_CHOICES), widget=bootstrap.Select()) dob = forms.DateField(label=_('Date of birth'), required=False, widget=bootstrap.SelectDateWidget( years=range(datetime.datetime.now().year - 100, datetime.datetime.now().year + 1))) def clean_email(self): # Check if email is unique, email = self.cleaned_data["email"] try: get_user_model().objects.get_by_email(email) except ObjectDoesNotExist: return email raise forms.ValidationError(self.error_messages['duplicate_email']) def clean(self): """ if the user clicks the edit_again button a ValidationError is raised, to display the form again. (see post_post method in FormPreview) """ edit_again = self.data.get("_edit_again") if edit_again: raise forms.ValidationError('_edit_again', '_edit_again') return super().clean() @staticmethod def save_data(data, username_generator=default_username_generator): new_user = get_user_model()() new_user.username = username_generator(data.get('first_name'), data.get('last_name')) new_user.first_name = data.get('first_name') new_user.last_name = data.get('last_name') new_user.language = data.get('language') new_user.timezone = data.get('timezone') new_user.gender = data.get('gender') new_user.dob = data.get('dob') new_user.is_active = False new_user.set_unusable_password() if 'picture' in data: new_user.picture = data.get('picture') new_user.save() new_user.create_primary_email(email=data.get('email')) user_address = UserAddress() user_address.primary = True user_address.user = new_user user_address.address_type = 'home' user_address.country = data['country'] user_address.city = data['city'] user_address.addressee = "%s %s" % (data.get('first_name'), data.get('last_name')) user_address.save() registration_profile = RegistrationProfile.objects.create( user=new_user) registration_profile.about_me = data['about_me'] registration_profile.known_person1_first_name = data[ 'known_person1_first_name'] registration_profile.known_person1_last_name = data[ 'known_person1_last_name'] registration_profile.known_person2_first_name = data[ 'known_person2_first_name'] registration_profile.known_person2_last_name = data[ 'known_person2_last_name'] registration_profile.save() return registration_profile
class AdminRegionForm(BaseForm): email_value = EmailFieldLower(required=True, label=_("Email address")) organisation_country = ModelChoiceField(queryset=None, required=True, label=_("country (org.)"), widget=bootstrap.Select2()) class Meta: model = AdminRegion fields = ('name', 'homepage', 'organisation_country', 'is_active') widgets = { 'homepage': bootstrap.TextInput(attrs={'size': 50}), 'organisation_country': bootstrap.Select2(), 'name': bootstrap.TextInput(attrs={'size': 50}), } def __init__(self, *args, **kwargs): self.user = kwargs.pop('user') # remove custom user keyword super().__init__(*args, **kwargs) self.fields[ 'organisation_country'].queryset = self.user.get_administrable_region_countries( ) if self.instance.email: self.fields['email_value'].initial = force_str(self.instance.email) else: self.fields['email_value'].initial = SSO_ORGANISATION_EMAIL_DOMAIN def clean_email_value(self): """ the new email address must be ending with SSO_ORGANISATION_EMAIL_DOMAIN """ email_value = self.cleaned_data['email_value'] if SSO_ORGANISATION_EMAIL_DOMAIN and email_value[ -len(SSO_ORGANISATION_EMAIL_DOMAIN ):] != SSO_ORGANISATION_EMAIL_DOMAIN: msg = _( 'The email address of the center must be ending with %(domain)s' ) % { 'domain': SSO_ORGANISATION_EMAIL_DOMAIN } raise ValidationError(msg) if Email.objects.filter(email=email_value).exclude( adminregion=self.instance).exists(): msg = _('The email address already exists') raise ValidationError(msg) return email_value def save(self, commit=True): instance = super().save(commit) if 'email_value' in self.changed_data: if self.instance.email: self.instance.email.email = self.cleaned_data['email_value'] self.instance.email.save() else: # create email object email = Email(email_type=REGION_EMAIL_TYPE, permission=PERM_DWB, email=self.cleaned_data['email_value']) email.save() instance.email = email instance.save() return instance