def validate(self, attrs): validated_attrs = super().validate(attrs) status_type_url = validated_attrs['status_type'] # dynamic so that it can be mocked in tests easily Client = import_string(settings.ZDS_CLIENT_CLASS) client = Client.from_url(status_type_url) client.auth = APICredential.get_auth( status_type_url, scopes=['zds.scopes.zaaktypes.lezen']) try: status_type = client.retrieve('statustype', url=status_type_url) validated_attrs['__is_eindstatus'] = status_type['isEindstatus'] except requests.HTTPError as exc: raise serializers.ValidationError( exc.args[0], code='relation-validation-error') from exc except KeyError as exc: raise serializers.ValidationError( exc.args[0], code='relation-validation-error') from exc # validate that all InformationObjects have indicatieGebruiksrecht set if validated_attrs['__is_eindstatus']: zaak = validated_attrs['zaak'] zios = zaak.zaakinformatieobject_set.all() for zio in zios: io_url = zio.informatieobject client = Client.from_url(io_url) client.auth = APICredential.get_auth( io_url, scopes=['zds.scopes.zaaktypes.lezen']) informatieobject = client.retrieve( 'enkelvoudiginformatieobject', url=io_url) if informatieobject['indicatieGebruiksrecht'] is None: raise serializers.ValidationError( "Er zijn gerelateerde informatieobjecten waarvoor `indicatieGebruiksrecht` nog niet " "gespecifieerd is. Je moet deze zetten voor je de zaak kan afsluiten.", code='indicatiegebruiksrecht-unset') brondatum_calculator = BrondatumCalculator( zaak, validated_attrs['datum_status_gezet']) try: brondatum_calculator.calculate() except Resultaat.DoesNotExist as exc: raise serializers.ValidationError( exc.args[0], code='resultaat-does-not-exist') from exc except DetermineProcessEndDateException as exc: # ideally, we'd like to do this in the validate function, but that's unfortunately too # early since we don't know the end date yet # thought: we _can_ use the datumStatusGezet though! raise serializers.ValidationError( exc.args[0], code='archiefactiedatum-error') # nasty to pass state around... self.context['brondatum_calculator'] = brondatum_calculator return validated_attrs
def fetch_object(url: str, do_underscoreize=True) -> dict: from vng_api_common.models import APICredential client_auth = APICredential.get_auth(url) headers = client_auth.credentials() if client_auth else {} try: response = requests.get(url, headers=headers) except requests.exceptions.RequestException as exc: raise FetchError(exc.args[0]) from exc try: response.raise_for_status() except requests.HTTPError as exc: raise FetchError(exc.args[0]) from exc try: data = response.json() except json.JSONDecodeError as exc: raise FetchJsonError(exc.args[0]) from exc if not do_underscoreize: return data return underscoreize(data)
def sync_delete_zio(relation: ZaakInformatieObject): zaak_url = get_absolute_url("zaak-detail", relation.zaak.uuid) logger.info("Zaak: %s", zaak_url) logger.info("Informatieobject: %s", relation.informatieobject) # Define the remote resource with which we need to interact resource = "objectinformatieobject" client = Client.from_url(relation.informatieobject) client.auth = APICredential.get_auth(relation.informatieobject) # Retrieve the url of the relation between the object and # the informatieobject response = client.list( resource, query_params={ "object": zaak_url, "informatieobject": relation.informatieobject, }, ) try: relation_url = response[0]["url"] except IndexError as exc: msg = "No relations found in DRC for this Zaak" logger.error(msg, exc_info=1) raise IndexError(msg) from exc try: client.delete(resource, url=relation_url) except Exception as exc: logger.error(f"Could not delete remote relation", exc_info=1) raise SyncError(f"Could not delete remote relation") from exc
def get_ztc_auth(url: str) -> dict: logger.info("Authenticating for %s", url) auth = APICredential.get_auth(url, scopes=["zds.scopes.zaaktypes.lezen"]) if auth is None: logger.warning("Could not authenticate for %s", url) return {} return auth.credentials()
def __call__(self, context: OrderedDict): object_url = context['object'] informatieobject_uuid = str( context['informatieobject'].latest_version.uuid) object_type = context['object_type'] informatieobject_url = get_absolute_url( 'enkelvoudiginformatieobject-detail', uuid=informatieobject_uuid) # dynamic so that it can be mocked in tests easily Client = import_string(settings.ZDS_CLIENT_CLASS) client = Client.from_url(object_url) client.auth = APICredential.get_auth(object_url) try: if object_type == 'zaak': resource = 'zaakinformatieobject' component = 'ZRC' elif object_type == 'besluit': resource = 'besluitinformatieobject' component = 'BRC' oios = client.list(resource, query_params={ object_type: object_url, 'informatieobject': informatieobject_url }) except ClientError as exc: raise serializers.ValidationError( exc.args[0], code='relation-validation-error') from exc if len(oios) == 0: raise serializers.ValidationError( self.message.format(component=component), code=self.code)
def __call__(self, object_informatie_object: ObjectInformatieObject): object_url = object_informatie_object.object informatieobject_url = get_absolute_url( 'enkelvoudiginformatieobject-detail', uuid=object_informatie_object.informatieobject.latest_version.uuid) Client = import_string(settings.ZDS_CLIENT_CLASS) client = Client.from_url(object_url) client.auth = APICredential.get_auth(object_url) resource = f"{object_informatie_object.object_type}informatieobject" try: relations = client.list(resource, query_params={ object_informatie_object.object_type: object_url, 'informatieobject': informatieobject_url, }) except ClientError as exc: raise serializers.ValidationError( exc.args[0], code='relation-lookup-error') from exc if len(relations) >= 1: raise serializers.ValidationError(self.message, code=self.code)
def __call__(self, objectklantinteractie: ObjectContactMoment): object_url = objectklantinteractie.object klantinteractie_uuid = getattr(objectklantinteractie, self.resource_name).uuid klantinteractie_url = get_absolute_url(f"{self.resource_name}-detail", uuid=klantinteractie_uuid) Client = import_string(settings.ZDS_CLIENT_CLASS) client = Client.from_url(object_url) client.auth = APICredential.get_auth(object_url) resource = f"{objectklantinteractie.object_type}{self.resource_name}" try: relations = client.list( resource, query_params={ objectklantinteractie.object_type: object_url, f"{self.resource_name}": klantinteractie_url, }, ) except ClientError as exc: raise serializers.ValidationError( exc.args[0], code="relation-lookup-error") from exc if len(relations) >= 1: raise serializers.ValidationError(self.message, code=self.code)
def sync_create_zaakcontactmoment(relation: ZaakContactMoment): zaak_url = get_absolute_url("zaak-detail", relation.zaak.uuid) logger.info("Zaak: %s", zaak_url) logger.info("Contactmoment: %s", relation.contactmoment) # Define the remote resource with which we need to interact resource = "objectcontactmoment" client = Client.from_url(relation.contactmoment) client.auth = APICredential.get_auth(relation.contactmoment) try: response = client.create( resource, { "object": zaak_url, "contactmoment": relation.contactmoment, "objectType": "zaak", }, ) except Exception as exc: logger.error(f"Could not create remote relation", exc_info=1) raise SyncError(f"Could not create remote relation") from exc # save ZaakBesluit url for delete signal relation._objectcontactmoment = response["url"] relation.save()
def sync_create(relation: ZaakInformatieObject): operation = 'create' # build the URL of the Zaak path = reverse('zaak-detail', kwargs={ 'version': settings.REST_FRAMEWORK['DEFAULT_VERSION'], 'uuid': relation.zaak.uuid, }) domain = Site.objects.get_current().domain protocol = 'https' if settings.IS_HTTPS else 'http' zaak_url = f'{protocol}://{domain}{path}' logger.info("Zaak: %s", zaak_url) logger.info("Informatieobject: %s", relation.informatieobject) # Define the remote resource with which we need to interact resource = 'objectinformatieobject' client = Client.from_url(relation.informatieobject) client.auth = APICredential.get_auth(relation.informatieobject) try: client.create( resource, { 'object': zaak_url, 'informatieobject': relation.informatieobject, 'objectType': 'zaak' }) except Exception as exc: logger.error(f"Could not {operation} remote relation", exc_info=1) raise SyncError(f"Could not {operation} remote relation") from exc
def get_auth(url: str) -> dict: logger.info("Authenticating for %s", url) auth = APICredential.get_auth(url) if auth is None: logger.warning("Could not authenticate for %s", url) return {} return auth.credentials()
def delete_remote_oio(oio_url: str) -> None: client_auth = APICredential.get_auth(oio_url) if client_auth is None: logger.warning("Missing credentials for %s", oio_url) headers = client_auth.credentials() if client_auth else {} response = requests.delete(oio_url, headers=headers) response.raise_for_status()
def fetch_object(resource: str, url: str) -> dict: """ Fetch a remote object by URL. """ Client = import_string(settings.ZDS_CLIENT_CLASS) client = Client.from_url(url) client.auth = APICredential.get_auth(url) obj = client.retrieve(resource, url=url) return obj
def _get_zaaktype(self, zaaktype_url: str) -> dict: if not hasattr(self, "_zaaktype"): # dynamic so that it can be mocked in tests easily Client = import_string(settings.ZDS_CLIENT_CLASS) client = Client.from_url(zaaktype_url) client.auth = APICredential.get_auth( zaaktype_url, scopes=["zds.scopes.zaaktypes.lezen"]) self._zaaktype = client.request(zaaktype_url, "zaaktype") return self._zaaktype
def _get_eigenschap(self, eigenschap_url): if not hasattr(self, "_eigenschap"): self._eigenschap = None if eigenschap_url: Client = import_string(settings.ZDS_CLIENT_CLASS) client = Client.from_url(eigenschap_url) client.auth = APICredential.get_auth( eigenschap_url, scopes=["zds.scopes.zaaktypes.lezen"]) self._eigenschap = client.request(eigenschap_url, "eigenschap") return self._eigenschap
def sync_delete_zaakverzoek(relation: ZaakVerzoek): resource = "objectverzoek" client = Client.from_url(relation.verzoek) client.auth = APICredential.get_auth(relation.verzoek) try: client.delete(resource, url=relation._objectverzoek) except Exception as exc: logger.error(f"Could not delete remote relation", exc_info=1) raise SyncError(f"Could not delete remote relation") from exc
def sync_delete_zaakcontactmoment(relation: ZaakContactMoment): resource = "objectcontactmoment" client = Client.from_url(relation.contactmoment) client.auth = APICredential.get_auth(relation.contactmoment) try: client.delete(resource, url=relation._objectcontactmoment) except Exception as exc: logger.error(f"Could not delete remote relation", exc_info=1) raise SyncError(f"Could not delete remote relation") from exc
def _derive_roltype_attributes(self): if self.omschrijving and self.omschrijving_generiek: return Client = import_string(settings.ZDS_CLIENT_CLASS) client = Client.from_url(self.roltype) client.auth = APICredential.get_auth(self.roltype) roltype = client.retrieve("roltype", url=self.roltype) self.omschrijving = roltype["omschrijving"] self.omschrijving_generiek = roltype["omschrijvingGeneriek"]
def _get_informatieobjecttype(self, informatieobjecttype_url: str) -> dict: if not hasattr(self, 'informatieobjecttype'): # dynamic so that it can be mocked in tests easily Client = import_string(settings.ZDS_CLIENT_CLASS) client = Client.from_url(informatieobjecttype_url) client.auth = APICredential.get_auth( informatieobjecttype_url, scopes=['zds.scopes.zaaktypes.lezen'] ) self._informatieobjecttype = client.request(informatieobjecttype_url, 'informatieobjecttype') return self._informatieobjecttype
def _get_resultaat_type(self, resultaat_type_url): if not hasattr(self, '_resultaat_type'): self._resultaat_type = None if resultaat_type_url: Client = import_string(settings.ZDS_CLIENT_CLASS) client = Client.from_url(resultaat_type_url) client.auth = APICredential.get_auth( resultaat_type_url, scopes=['zds.scopes.zaaktypes.lezen']) self._resultaat_type = client.request(resultaat_type_url, 'resultaattype') return self._resultaat_type
def _get_resultaattype(self, resultaattype_url: str): if not hasattr(self, "_resultaattype"): self._resultaattype = None if resultaattype_url: Client = import_string(settings.ZDS_CLIENT_CLASS) client = Client.from_url(resultaattype_url) client.auth = APICredential.get_auth( resultaattype_url, scopes=["zds.scopes.zaaktypes.lezen"]) self._resultaattype = client.retrieve("resultaattype", url=resultaattype_url) return self._resultaattype
def create_remote_zaakbesluit(besluit_url: str, zaak_url: str) -> dict: client_auth = APICredential.get_auth(zaak_url) if client_auth is None: logger.warning("Missing credentials for %s", zaak_url) list_url = f"{zaak_url}/besluiten" headers = client_auth.credentials() if client_auth else {} body = {"besluit": besluit_url} response = requests.post(list_url, json=body, headers=headers) response.raise_for_status() return response.json()
def validate(self, attrs): validated_attrs = super().validate(attrs) status_type_url = validated_attrs['status_type'] # dynamic so that it can be mocked in tests easily Client = import_string(settings.ZDS_CLIENT_CLASS) client = Client.from_url(status_type_url) client.auth = APICredential.get_auth( status_type_url, scopes=['zds.scopes.zaaktypes.lezen']) try: status_type = client.request(status_type_url, 'statustype') validated_attrs['__is_eindstatus'] = status_type['isEindstatus'] except requests.HTTPError as exc: raise serializers.ValidationError( exc.args[0], code='relation-validation-error') from exc except KeyError as exc: raise serializers.ValidationError( exc.args[0], code='relation-validation-error') from exc # validate that all InformationObjects have indicatieGebruiksrecht set if validated_attrs['__is_eindstatus']: zios = validated_attrs['zaak'].zaakinformatieobject_set.all() for zio in zios: io_url = zio.informatieobject client = Client.from_url(io_url) client.auth = APICredential.get_auth( io_url, scopes=['zds.scopes.zaaktypes.lezen']) informatieobject = client.request( io_url, 'enkelvoudiginformatieobject') if informatieobject['indicatieGebruiksrecht'] is None: raise serializers.ValidationError( "Er zijn gerelateerde informatieobjecten waarvoor `indicatieGebruiksrecht` nog niet " "gespecifieerd is. Je moet deze zetten voor je de zaak kan afsluiten.", code='indicatiegebruiksrecht-unset') return validated_attrs
def __call__(self, context: OrderedDict): object_url = context["object"] informatieobject_uuid = str( context["informatieobject"].latest_version.uuid) object_type = context["object_type"] informatieobject_url = get_absolute_url( "enkelvoudiginformatieobject-detail", uuid=informatieobject_uuid) # dynamic so that it can be mocked in tests easily Client = import_string(settings.ZDS_CLIENT_CLASS) client = Client.from_url(object_url) client.auth = APICredential.get_auth(object_url) try: if object_type == "zaak": resource = "zaakinformatieobject" component = "ZRC" oas_schema = settings.ZRC_API_SPEC elif object_type == "besluit": resource = "besluitinformatieobject" component = "BRC" oas_schema = settings.BRC_API_SPEC try: ResourceValidator( object_type.capitalize(), oas_schema, get_auth=get_zrc_auth, headers={"Accept-Crs": "EPSG:4326"}, )(object_url) except exceptions.ValidationError as exc: raise serializers.ValidationError({"object": exc.detail}, code=ResourceValidator.code) oios = client.list( resource, query_params={ object_type: object_url, "informatieobject": informatieobject_url, }, ) except ClientError as exc: raise serializers.ValidationError( exc.args[0], code="relation-validation-error") from exc if len(oios) == 0: raise serializers.ValidationError( self.message.format(component=component), code=self.code)
def handle(self, **options): new_secrets = [ JWTSecret(id=old.id, identifier=old.identifier, secret=old.secret) for old in OldJWTSecret.objects.all() ] JWTSecret.objects.bulk_create(new_secrets) new_credentials = [ APICredential(id=old.id, api_root=old.api_root, client_id=old.client_id, secret=old.secret) for old in OldAPICredential.objects.all() ] APICredential.objects.bulk_create(new_credentials)
def _get_object(self) -> dict: """ Retrieve the `Object` specified as URL in `ZaakObject.object`. :return: A `dict` representing the object. """ if not hasattr(self, '_object'): object_url = self.object self._object = None if object_url: Client = import_string(settings.ZDS_CLIENT_CLASS) client = Client.from_url(object_url) client.auth = APICredential.get_auth(object_url) self._object = client.retrieve(self.object_type.lower(), url=object_url) return self._object
def get_zds_client(url: str): """ Retrieve a ZDS Client instance for the given API URL. The client respects the setting ``CUSTOM_CLIENT_FETCHER`` as used by vng-api-common, and will have the auth configured. """ Client = get_client_class() default = Client.from_url(url) if getattr(settings, "CUSTOM_CLIENT_FETCHER", None): client = import_string(settings.CUSTOM_CLIENT_FETCHER)(default.base_url) return client else: default.auth = APICredential.get_auth(url) return default
def create_remote_oio(io_url: str, object_url: str, object_type: str = "zaak") -> dict: client_auth = APICredential.get_auth(io_url) if client_auth is None: logger.warning("Missing credentials for %s", io_url) url = _get_oio_endpoint(io_url) headers = client_auth.credentials() if client_auth else {} body = { "informatieobject": io_url, "object": object_url, "objectType": object_type } response = requests.post(url, json=body, headers=headers) response.raise_for_status() return response.json()
def _get_information_objects(self) -> list: if not hasattr(self, "_information_objects"): self._information_objects = [] if self.instance: Client = import_string(settings.ZDS_CLIENT_CLASS) zios = self.instance.zaakinformatieobject_set.all() for zio in zios: io_url = zio.informatieobject client = Client.from_url(io_url) client.auth = APICredential.get_auth( io_url, scopes=["scopes.documenten.lezen"]) informatieobject = client.request( io_url, "enkelvoudiginformatieobject") self._information_objects.append(informatieobject) return self._information_objects
def __call__(self, attrs: OrderedDict): object_url = attrs["object"] object_type = attrs["object_type"] klantinteractie_url = get_absolute_url( f"{self.resource_name}-detail", uuid=attrs[self.resource_name].uuid) # dynamic so that it can be mocked in tests easily Client = import_string(settings.ZDS_CLIENT_CLASS) client = Client.from_url(object_url) client.auth = APICredential.get_auth(object_url) resource = f"{object_type}{self.resource_name}" oas_schema = settings.ZRC_API_SPEC try: ResourceValidator( object_type.capitalize(), oas_schema, get_auth=get_auth, headers={"Accept-Crs": "EPSG:4326"}, )(object_url) except exceptions.ValidationError as exc: raise serializers.ValidationError({"object": exc.detail}, code=ResourceValidator.code) try: relations = client.list( resource, query_params={ object_type: object_url, f"{self.resource_name}": klantinteractie_url, }, ) except ClientError as exc: raise serializers.ValidationError( exc.args[0], code="relation-validation-error") from exc if len(relations) == 0: raise serializers.ValidationError( self.message.format(object=object_type), code=self.code)
def sync_delete(relation: ZaakInformatieObject): operation = 'delete' # build the URL of the Zaak path = reverse('zaak-detail', kwargs={ 'version': settings.REST_FRAMEWORK['DEFAULT_VERSION'], 'uuid': relation.zaak.uuid, }) domain = Site.objects.get_current().domain protocol = 'https' if settings.IS_HTTPS else 'http' zaak_url = f'{protocol}://{domain}{path}' logger.info("Zaak: %s", zaak_url) logger.info("Informatieobject: %s", relation.informatieobject) # Define the remote resource with which we need to interact resource = 'objectinformatieobject' client = Client.from_url(relation.informatieobject) client.auth = APICredential.get_auth(relation.informatieobject) # Retrieve the url of the relation between the object and # the informatieobject response = client.list(resource, query_params={ 'object': zaak_url, 'informatieobject': relation.informatieobject }) try: relation_url = response[0]['url'] except IndexError as exc: msg = "No relations found in DRC for this Zaak" logger.error(msg, exc_info=1) raise IndexError(msg) from exc try: client.delete(resource, url=relation_url) except Exception as exc: logger.error(f"Could not {operation} remote relation", exc_info=1) raise SyncError(f"Could not {operation} remote relation") from exc