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
Exemple #2
0
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()))
Exemple #3
0
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())
Exemple #4
0
class VisualisationCatalogueItemForm(forms.ModelForm):
    eligibility_criteria = DynamicArrayField(
        base_field=forms.CharField(), required=False
    )

    class Meta:
        model = VisualisationCatalogueItem
        fields = '__all__'
Exemple #5
0
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)
Exemple #9
0
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()))
Exemple #10
0
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)