예제 #1
0
def get_out_of_sync_autorisaties(field: str) -> List[Autorisatie]:
    to_delete = []
    for autorisatie in Autorisatie.objects.exclude(**{field: ""}):
        value = getattr(autorisatie, field)
        if not is_local_url(value):
            continue

        parsed = urlparse(value)

        try:
            get_resource_for_path(parsed.path)
        except ObjectDoesNotExist:
            to_delete.append(autorisatie)
    return to_delete
def migrate_from_url(apps, _):
    ZaakTypenRelatie = apps.get_model('datamodel.ZaakTypenRelatie')

    for relation in ZaakTypenRelatie.objects.all():
        zaaktype_naar = get_resource_for_path(relation.gerelateerd_zaaktype)
        relation.zaaktype_naar = zaaktype_naar
        relation.save()
예제 #3
0
    def has_permission(self, request: Request, view) -> bool:
        from rest_framework.viewsets import ViewSetMixin

        if bypass_permissions(request):
            return True

        scopes_required = get_required_scopes(view)
        component = self.get_component(view)

        if not self.permission_fields:
            return request.jwt_auth.has_auth(scopes_required, component)

        main_resource = self.get_main_resource()

        if view.action == "create":
            if view.__class__ is main_resource:
                main_object_data = request.data

            else:
                main_object_url = request.data[view.permission_main_object]
                main_object_path = urlparse(main_object_url).path
                main_object = get_resource_for_path(main_object_path)
                main_object_data = self.format_data(main_object, request)

            fields = self.get_fields(main_object_data)
            return request.jwt_auth.has_auth(scopes_required, component,
                                             **fields)

        # detect if this is an unsupported method - if it's a viewset and the
        # action was not mapped, it's not supported and DRF will catch it
        if view.action is None and isinstance(view, ViewSetMixin):
            return True

        # by default - check if the action is allowed at all
        return request.jwt_auth.has_auth(scopes_required, component)
예제 #4
0
    def has_permission(self, request: Request, view) -> bool:
        # permission checks run before the handler is determined. if there is no handler,
        # a "method is not allowed" must be raised, not an HTTP 403 (see #385)
        # this implementation works for both APIView and viewsets
        has_handler = hasattr(view, request.method.lower())
        if not has_handler:
            view.http_method_not_allowed(request)

        # JWTs are only valid for a short amount of time
        self.check_jwt_expiry(request.jwt_auth.payload)

        from rest_framework.viewsets import ViewSetMixin

        if bypass_permissions(request):
            return True

        scopes_required = get_required_scopes(view)
        component = self.get_component(view)

        if not self.permission_fields:
            return request.jwt_auth.has_auth(scopes_required, component)

        main_resource = self.get_main_resource()

        if view.action == "create":
            if view.__class__ is main_resource:
                main_object_data = request.data

            else:
                main_object_url = request.data[view.permission_main_object]
                main_object_path = urlparse(main_object_url).path
                try:
                    main_object = get_resource_for_path(main_object_path)
                except ObjectDoesNotExist:
                    raise ValidationError({
                        view.permission_main_object:
                        ValidationError(
                            _("The object does not exist in the database"),
                            code="object-does-not-exist",
                        ).detail
                    })
                except DjangoValidationError as exc:
                    err_dict = as_serializer_error(
                        ValidationError({view.permission_main_object: exc}))
                    raise ValidationError(err_dict)

                main_object_data = self.format_data(main_object, request)

            fields = self.get_fields(main_object_data)
            return request.jwt_auth.has_auth(scopes_required, component,
                                             **fields)

        # detect if this is an unsupported method - if it's a viewset and the
        # action was not mapped, it's not supported and DRF will catch it
        if view.action is None and isinstance(view, ViewSetMixin):
            return True

        # by default - check if the action is allowed at all
        return request.jwt_auth.has_auth(scopes_required, component)
예제 #5
0
def m2m_filter(queryset, name, value):
    parsed = urlparse(value)
    path = parsed.path
    try:
        object = get_resource_for_path(path)
    except ObjectDoesNotExist:
        return queryset.none()
    return queryset.filter(**{name: object})
예제 #6
0
 def _get_obj(self, view, request):
     """
     Overridden to ensure that the correct key is used to retrieve the url
     from the request data
     """
     main_obj_path = request.data.get(self.obj_path.split(".")[0], None)
     main_obj_url = urlparse(main_obj_path).path
     main_obj = get_resource_for_path(main_obj_url)
     return main_obj
예제 #7
0
 def get_loose_fk_object(self,
                         authorization,
                         local=True) -> Union[models.Model, str]:
     loose_fk_url = getattr(authorization, self.loose_fk_field)
     if local:
         loose_fk_object_path = urlparse(loose_fk_url).path
         loose_fk_object = get_resource_for_path(loose_fk_object_path)
     else:
         loose_fk_object = loose_fk_url
     return loose_fk_object
예제 #8
0
파일: query.py 프로젝트: ElenaFdR/open-zaak
    def filter_for_authorizations(
            self, scope: Scope,
            authorizations: models.QuerySet) -> models.QuerySet:
        """
        Filter objects whitelisted by the authorizations.

        For BRC, authorizations are defined around ``Autorisatie.besluittype``,
        limiting scopes that apply for the ``besluittype`` at hand.

        This means that ``besluiten`` are included if, and only if:

        * the ``besluittype`` is provided in ``authorizations``
        * the scopes for the ``besluittype`` in each ``authorization`` contain the
          required``scope``

        :param scope: a (possibly complex) scope that must be granted on the
          authorizations
        :param authorizations: queryset of
          :class:`vng_api_common.authorizations.Autorisatie` objects

        :return: a queryset of filtered results according to the
          authorizations provided
        """
        prefix = ("" if not self.authorizations_lookup else
                  f"{self.authorizations_lookup}__")

        # keep a list of allowed besluittypen
        besluittypen = []
        for authorization in authorizations:
            if scope.is_contained_in(authorization.scopes):
                besluittype_path = urlparse(authorization.besluittype).path
                besluittype = get_resource_for_path(besluittype_path)
                besluittypen.append(besluittype)

        # filtering:
        # * only allow the white-listed besluittypen, explicitly
        queryset = self.filter(**{f"{prefix}besluittype__in": besluittypen})
        return queryset
예제 #9
0
    def filter_for_authorizations(
            self, scope: Scope,
            authorizations: models.QuerySet) -> models.QuerySet:
        """
        Filter objects whitelisted by the authorizations.

        For ZRC, authorizations are defined around ``Autorisatie.zaaktype``,
        with a ``max_vertrouwelijkheidaanduiding`` limiting the confidentiality
        level of ``zaken`` (inclusive), and scopes that apply for the
        ``zaaktype`` at hand.

        This means that ``zaken`` are included if, and only if:

        * the ``zaaktype`` is provided in ``authorizations``
        * the scopes for the ``zaaktype`` in each ``authorization`` contain the
          required``scope``
        * the ``zaak.vertrouwelijkheidaanduiding`` is less then or equal to the
          ``authorization.max_vertrouwelijkheidaanduiding``

        :param scope: a (possibly complex) scope that must be granted on the
          authorizations
        :param authorizations: queryset of
          :class:`vng_api_common.authorizations.Autorisatie` objects

        :return: a queryset of filtered results according to the
          authorizations provided
        """
        # keep a list of allowed zaaktypen
        zaaktypen = []

        prefix = ("" if not self.authorizations_lookup else
                  f"{self.authorizations_lookup}__")

        # annotate the queryset so we can map a string value to a logical number
        order_case = VertrouwelijkheidsAanduiding.get_order_expression(
            f"{prefix}vertrouwelijkheidaanduiding")

        # build the case/when to map the max_vertrouwelijkheidaanduiding based
        # on the ``zaaktype``
        vertrouwelijkheidaanduiding_whens = []
        for authorization in authorizations:
            # test if this authorization has the scope that's needed
            if not scope.is_contained_in(authorization.scopes):
                continue

            # this zaaktype is allowed
            zaaktype_path = urlparse(authorization.zaaktype).path
            zaaktype = get_resource_for_path(zaaktype_path)
            zaaktypen.append(zaaktype)

            # extract the order and map it to the database value
            choice_item = VertrouwelijkheidsAanduiding.get_choice(
                authorization.max_vertrouwelijkheidaanduiding)
            vertrouwelijkheidaanduiding_whens.append(
                When(**{f"{prefix}zaaktype": zaaktype},
                     then=Value(choice_item.order)))

        # apply the order annnotation so we can filter later
        annotations = {f"{prefix}_va_order": order_case}
        # filtering:
        # * only allow the white-listed zaaktypen, explicitly
        # * apply the filtering to limit cases within case-types to the maximal
        #   confidentiality level
        filters = {
            f"{prefix}zaaktype__in":
            zaaktypen,
            f"{prefix}_va_order__lte":
            Case(*vertrouwelijkheidaanduiding_whens,
                 output_field=IntegerField()),
        }

        # bring it all together now to build the resulting queryset
        queryset = self.annotate(**annotations).filter(**filters)
        return queryset
예제 #10
0
 def resolve_io_type(self, url: str):
     try:
         return get_resource_for_path(urlparse(url).path)
     except InformatieObjectType.DoesNotExist:
         return super().load(url, model=InformatieObjectType)
예제 #11
0
def m2m_filter(queryset, name, value):
    object = get_resource_for_path(value)
    return queryset.filter(**{name: object})
예제 #12
0
def test_get_resource_for_path_with_trailing_slash(path, exc):
    with pytest.raises(exc):
        get_resource_for_path(path)
예제 #13
0
    def filter_for_authorizations(
            self, scope: Scope,
            authorizations: models.QuerySet) -> models.QuerySet:
        """
        Filter objects whitelisted by the authorizations.

        For DRC, authorizations are defined around ``Autorisatie.informatieobjecttype``,
        with a ``max_vertrouwelijkheidaanduiding`` limiting the confidentiality
        level of ``informatieobjecten`` (inclusive), and scopes that apply for the
        ``informatieobjecttype`` at hand.

        This means that ``informatieobjecten`` are included if, and only if:

        * the ``informatieobjecttype`` is provided in ``authorizations``
        * the scopes for the ``informatieobjecttype`` in each ``authorization`` contain the
          required``scope``
        * the ``informatieobjecttype.vertrouwelijkheidaanduiding`` is less then or equal to the
          ``authorization.max_vertrouwelijkheidaanduiding``

        :param scope: a (possibly complex) scope that must be granted on the
          authorizations
        :param authorizations: queryset of
          :class:`vng_api_common.authorizations.Autorisatie` objects

        :return: a queryset of filtered results according to the
          authorizations provided
        """
        # keep a list of allowed informatieobjecttypen
        informatieobjecttypen = []

        # annotate the queryset so we can map a string value to a logical number
        order_case = VertrouwelijkheidsAanduiding.get_order_expression(
            "vertrouwelijkheidaanduiding")

        # build the case/when to map the max_vertrouwelijkheidaanduiding based
        # on the ``informatieobjecttype``
        vertrouwelijkheidaanduiding_whens = []
        for authorization in authorizations:
            # test if this authorization has the scope that's needed
            if not scope.is_contained_in(authorization.scopes):
                continue

            # this informatieobjecttype is allowed
            informatieobjecttype_path = urlparse(
                authorization.informatieobjecttype).path
            informatieobjecttype = get_resource_for_path(
                informatieobjecttype_path)
            informatieobjecttypen.append(informatieobjecttype)

            # extract the order and map it to the database value
            choice_item = VertrouwelijkheidsAanduiding.get_choice(
                authorization.max_vertrouwelijkheidaanduiding)
            vertrouwelijkheidaanduiding_whens.append(
                When(
                    **{"informatieobjecttype": informatieobjecttype},
                    then=Value(choice_item.order),
                ))

        # apply the order annnotation so we can filter later
        annotations = {"_va_order": order_case}
        # filtering:
        # * only allow the white-listed informatieobjecttypen, explicitly
        # * apply the filtering to limit cases within case-types to the maximal
        #   confidentiality level
        filters = {
            "informatieobjecttype__in":
            informatieobjecttypen,
            "_va_order__lte":
            Case(*vertrouwelijkheidaanduiding_whens,
                 output_field=IntegerField()),
        }
        if self.authorizations_lookup:
            # If the current queryset is not an InformatieObjectQuerySet, first
            # retrieve the canonical IDs of EnkelvoudigInformatieObjects
            # for which the user is authorized and then return the objects
            # related to those EnkelvoudigInformatieObjectCanonicals
            model = apps.get_model("documenten", "EnkelvoudigInformatieObject")
            filtered = (model.objects.annotate(**annotations).filter(
                **filters).values("canonical"))
            queryset = self.filter(informatieobject__in=filtered)
        # bring it all together now to build the resulting queryset
        else:
            queryset = self.annotate(**annotations).filter(**filters)
        return queryset