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
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
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 informatieobjecttypen.append(authorization.informatieobjecttype) # extract the order and map it to the database value choice_item = VertrouwelijkheidsAanduiding.get_choice( authorization.max_vertrouwelijkheidaanduiding ) vertrouwelijkheidaanduiding_whens.append( When( **{"informatieobjecttype": authorization.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("datamodel", "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