def test_default(): default = ["1"] field = DynamicArrayField(CharField(max_length=10), required=True, default=default) data = [] cleaned_data = field.clean(data) assert cleaned_data == default
class VisualisationCatalogueItemForm(AutoCompleteUserFieldsMixin, forms.ModelForm): eligibility_criteria = DynamicArrayField(base_field=forms.CharField(), required=False) authorized_users = forms.ModelMultipleChoiceField( required=False, widget=FilteredSelectMultiple("users", False), queryset=get_user_model().objects.filter().order_by("email"), ) can_change_user_permission_codename = "datasets.change_visualisationuserpermission" class Meta: model = VisualisationCatalogueItem fields = "__all__" widgets = {"type": forms.HiddenInput()} def __init__(self, *args, **kwargs): user = kwargs.pop("user") super().__init__(*args, **kwargs) is_instance = "instance" in kwargs and kwargs["instance"] self.fields["authorized_users"].initial = ( get_user_model().objects.filter( visualisationuserpermission__visualisation=kwargs["instance"]) if is_instance else get_user_model().objects.none()) if not user.is_superuser and not user.has_perm( self.can_change_user_permission_codename): self.fields["user_access_type"].disabled = True self.fields["authorized_users"].disabled = True self.fields["authorized_users"].widget = SelectMultiple(choices=( (user.id, user.email) for user in self.fields["authorized_users"].queryset.all()))
class BaseDatasetForm(forms.ModelForm): type = forms.HiddenInput() eligibility_criteria = DynamicArrayField(base_field=forms.CharField(), required=False) requires_authorization = forms.BooleanField( label='Each user must be individually authorized to access the data', required=False, ) authorized_users = forms.ModelMultipleChoiceField( required=False, widget=FilteredSelectMultiple('users', False), queryset=get_user_model().objects.filter().order_by('email'), ) class Meta: model = DataSet fields = '__all__' widgets = {'type': forms.HiddenInput()} def __init__(self, *args, **kwargs): kwargs['initial'] = {'type': self.dataset_type} super().__init__(*args, **kwargs) is_instance = 'instance' in kwargs and kwargs['instance'] self.fields['requires_authorization'].initial = ( kwargs['instance'].user_access_type == 'REQUIRES_AUTHORIZATION' if is_instance else True) self.fields['authorized_users'].initial = ( get_user_model().objects.filter( datasetuserpermission__dataset=kwargs['instance']) if is_instance else get_user_model().objects.none())
class VisualisationCatalogueItemForm(forms.ModelForm): eligibility_criteria = DynamicArrayField( base_field=forms.CharField(), required=False ) class Meta: model = VisualisationCatalogueItem fields = '__all__'
class BaseDatasetForm(forms.ModelForm): type = forms.HiddenInput() eligibility_criteria = DynamicArrayField( base_field=forms.CharField(), required=False ) requires_authorization = forms.BooleanField( label='Each user must be individually authorized to access the data', required=False, ) authorized_users = forms.ModelMultipleChoiceField( required=False, widget=FilteredSelectMultiple('users', False), queryset=get_user_model().objects.filter().order_by('email'), ) # Invalid dataset type - must be overridden by the subclass. dataset_type = -1 can_change_user_permission_codename = None class Meta: model = DataSet fields = '__all__' widgets = {'type': forms.HiddenInput()} def __init__(self, *args, **kwargs): user = kwargs.pop('user') kwargs['initial'] = {'type': self.dataset_type} super().__init__(*args, **kwargs) is_instance = 'instance' in kwargs and kwargs['instance'] self.fields['requires_authorization'].initial = ( kwargs['instance'].user_access_type == 'REQUIRES_AUTHORIZATION' if is_instance else True ) self.fields['authorized_users'].initial = ( get_user_model().objects.filter( datasetuserpermission__dataset=kwargs['instance'] ) if is_instance else get_user_model().objects.none() ) if not user.is_superuser and not user.has_perm( self.can_change_user_permission_codename ): self.fields['requires_authorization'].disabled = True self.fields['authorized_users'].disabled = True self.fields['authorized_users'].widget = SelectMultiple( choices=( (user.id, user.email) for user in self.fields['authorized_users'].queryset.all() ) )
def test_default_different_values(self, model_class, init_value, expected_value): default = [1] data = {} if init_value is not None: data["array"] = init_value field = DynamicArrayField(IntegerField(), required=True, default=default) form = form_factory(model_class, array=field)(data=data) assert form.is_valid() assert form.cleaned_data["array"] == expected_value
def test_field_required(): field = DynamicArrayField(CharField(max_length=10), required=True) data = [] with pytest.raises(ValidationError): field.clean(data) data = ["12", "13"] field.clean(data)
class BaseDatasetForm(forms.ModelForm): type = forms.HiddenInput() eligibility_criteria = DynamicArrayField(base_field=forms.CharField(), required=False) requires_authorization = forms.BooleanField( label='Each user must be individually authorized to access the data', required=False, ) class Meta: model = DataSet fields = '__all__' widgets = {'type': forms.HiddenInput()} def __init__(self, *args, **kwargs): kwargs['initial'] = {'type': self.dataset_type} super().__init__(*args, **kwargs) is_instance = 'instance' in kwargs and kwargs['instance'] self.fields['requires_authorization'].initial = ( kwargs['instance'].user_access_type == 'REQUIRES_AUTHORIZATION' if is_instance else True)
class BaseDatasetForm(AutoCompleteUserFieldsMixin, forms.ModelForm): type = forms.HiddenInput() eligibility_criteria = DynamicArrayField(base_field=forms.CharField(), required=False) authorized_users = forms.ModelMultipleChoiceField( required=False, widget=FilteredSelectMultiple("users", False), queryset=get_user_model().objects.filter().order_by("email"), ) # Invalid dataset type - must be overridden by the subclass. dataset_type = -1 can_change_user_permission_codename = None class Meta: model = DataSet fields = "__all__" widgets = {"type": forms.HiddenInput()} def __init__(self, *args, **kwargs): user = kwargs.pop("user") kwargs["initial"] = {"type": self.dataset_type} super().__init__(*args, **kwargs) is_instance = "instance" in kwargs and kwargs["instance"] self.fields["authorized_users"].initial = ( get_user_model().objects.filter( datasetuserpermission__dataset=kwargs["instance"]) if is_instance else get_user_model().objects.none()) if not user.is_superuser and not user.has_perm( self.can_change_user_permission_codename): self.fields["user_access_type"].disabled = True self.fields["authorized_users"].disabled = True self.fields["authorized_users"].widget = SelectMultiple(choices=( (user.id, user.email) for user in self.fields["authorized_users"].queryset.all()))
class AutorisatieForm(forms.Form): component = forms.ChoiceField( label=_("component"), required=True, help_text=_("Component waarin deze autorisatie van toepassing is."), choices=ComponentTypes.choices, widget=forms.RadioSelect, ) scopes = forms.MultipleChoiceField( label=_("scopes"), required=True, help_text=_("Scopes die van toepassing zijn binnen deze autorisatie"), choices=get_scope_choices, widget=forms.CheckboxSelectMultiple, ) related_type_selection = forms.ChoiceField( label=_("{verbose_name}"), required=False, help_text=_( "Kies hoe je gerelateerde typen wil aanduiden. " "De toegekende scopes zijn enkel van toepassing op objecten van " "dit/deze specifieke {verbose_name_plural}"), choices=RelatedTypeSelectionMethods.choices, widget=forms.RadioSelect, ) vertrouwelijkheidaanduiding = forms.ChoiceField( label=_("maximale vertrouwelijkheidaanduiding"), required=False, help_text=_( "De maximale vertrouwelijkheidaanduiding waartoe consumers toegang hebben. " "Indien objecten van het betreffende {verbose_name} een striktere " "vertrouwelijkheidaanduiding hebben, dan zijn deze objecten niet " "toegangelijk voor de consumer."), choices=VertrouwelijkheidsAanduiding.choices, widget=forms.RadioSelect, ) zaaktypen = forms.ModelMultipleChoiceField( label=_("zaaktypen"), required=False, help_text=_("De zaaktypen waarop deze autorisatie van toepassing is."), queryset=ZaakType.objects.all(), widget=forms.CheckboxSelectMultiple, ) informatieobjecttypen = forms.ModelMultipleChoiceField( label=_("informatieobjecttypen"), required=False, help_text= _("De informatieobjecttypen waarop deze autorisatie van toepassing is." ), queryset=InformatieObjectType.objects.all(), widget=forms.CheckboxSelectMultiple, ) besluittypen = forms.ModelMultipleChoiceField( label=_("besluittypen"), required=False, help_text=_( "De besluittypen waarop deze autorisatie van toepassing is."), queryset=BesluitType.objects.all(), widget=forms.CheckboxSelectMultiple, ) externe_typen = DynamicArrayField( base_field=forms.URLField( max_length=1000, required=True, ), required=False, error_messages={"item_invalid": ""}, ) def clean(self): super().clean() component = self.cleaned_data.get("component") # didn't pass validation, can't do anything else as it all relies on this # field if not component: return self._validate_scopes(component) self._validate_required_fields(component) self._validate_external_types(component) def _validate_scopes(self, component: str): scopes = self.cleaned_data.get("scopes") # can't do anything if there are no scopes selected if scopes is None: return valid_prefixes = COMPONENT_TO_PREFIXES_MAP[component] invalid_scopes = [ scope for scope in scopes if not any(scope.startswith(prefix) for prefix in valid_prefixes) ] if invalid_scopes: error = forms.ValidationError( _("De volgende scopes zijn geen geldige keuzes voor deze component: {scopes}" ).format(scopes=", ".join(invalid_scopes)), code="invalid", ) self.add_error("scopes", error) def _validate_required_fields(self, component: str): _field_info = COMPONENT_TO_FIELDS_MAP.get(component) if _field_info is None: return expected_fields = _field_info["required"] missing = [ field for field in expected_fields if not self.cleaned_data.get(field) ] for field in missing: error = forms.ValidationError( _("Je moet een keuze opgeven voor het veld: {field}").format( field=field), code="required", ) self.add_error(field, error) if "related_type_selection" not in expected_fields: return related_type_selection = self.cleaned_data.get( "related_type_selection") if related_type_selection != RelatedTypeSelectionMethods.manual_select: return # check that values for the typen have been selected manually types_field = _field_info["types_field"] if not self.cleaned_data.get( types_field) and not self.cleaned_data.get("externe_typen"): error = forms.ValidationError( _("Je moet minimaal 1 {verbose_name} kiezen").format( verbose_name=_field_info["verbose_name"]), code="required", ) self.add_error(types_field, error) def _validate_external_types(self, component): _field_info = COMPONENT_TO_FIELDS_MAP.get(component) if _field_info is None: return external_typen = self.cleaned_data.get("externe_typen") if not external_typen: return validator = ResourceValidator(_field_info["resource_name"], settings.ZTC_API_SPEC, get_auth=get_auth) for _type in external_typen: try: validator(_type) except exceptions.ValidationError as exc: error = forms.ValidationError(str(exc.detail[0]), code=exc.detail[0].code) self.add_error("externe_typen", error) def get_types(self, component): related_type_selection = self.cleaned_data.get( "related_type_selection") types = None if related_type_selection: _field_info = COMPONENT_TO_FIELDS_MAP[component] # pick the entire queryset and if related_type_selection in [ RelatedTypeSelectionMethods.all_current_and_future, RelatedTypeSelectionMethods.all_current, ]: types = self.fields[_field_info["types_field"]].queryset # only pick a queryset of the explicitly selected objects elif related_type_selection == RelatedTypeSelectionMethods.manual_select: types = self.cleaned_data.get(_field_info["types_field"]) return types def save(self, applicatie: Applicatie, request, commit=True): """ Save the Autorisatie data into the right Autorisatie objects. The form essentially condenses a bunch of fields, e.g. for each included 'zaaktype' an Autorisatie object is created. """ if not commit: return # forms beyond initial data that haven't changed -> nothing to do if not self.has_changed() and not self.initial: return # Fixed fields component = self.cleaned_data["component"] scopes = self.cleaned_data["scopes"] # dependent fields vertrouwelijkheidaanduiding = self.cleaned_data.get( "vertrouwelijkheidaanduiding", "") types = self.get_types(component) # install a handler for future objects related_type_selection = self.cleaned_data.get( "related_type_selection") if related_type_selection == RelatedTypeSelectionMethods.all_current_and_future: applicatie.autorisatie_specs.update_or_create( component=component, defaults={ "scopes": scopes, "max_vertrouwelijkheidaanduiding": vertrouwelijkheidaanduiding, }, ) autorisatie_kwargs = { "applicatie": applicatie, "component": component, "scopes": scopes, } if types is None: Autorisatie.objects.create(**autorisatie_kwargs) else: _field_info = COMPONENT_TO_FIELDS_MAP[component] autorisaties = [] for _type in types: data = autorisatie_kwargs.copy() url = request.build_absolute_uri(_type.get_absolute_api_url()) data[_field_info["_autorisatie_type_field"]] = url autorisaties.append( Autorisatie( max_vertrouwelijkheidaanduiding= vertrouwelijkheidaanduiding, **data, )) if self.cleaned_data.get("externe_typen"): for _type in self.cleaned_data.get("externe_typen"): data = autorisatie_kwargs.copy() data[_field_info["_autorisatie_type_field"]] = _type autorisaties.append( Autorisatie( max_vertrouwelijkheidaanduiding= vertrouwelijkheidaanduiding, **data, )) Autorisatie.objects.bulk_create(autorisaties)
def test_field_not_required(): field = DynamicArrayField(CharField(max_length=10), required=False) data = [] field.clean(data) data = ["12", "13"] field.clean(data)