Example #1
0
def test_client_from_url_thread_safe():
    client1 = Client.from_url(
        "https://example.com/api/v1/zaken/7C61204C-BFD8-4A66-B826-5DF8CB7F9A60"
    )
    client2 = Client.from_url(
        "https://example2.com/api/v2/zaken/7C61204C-BFD8-4A66-B826-5DF8CB7F9A60"
    )

    assert client1.base_url == "https://example.com/api/v1/"
    assert client2.base_url == "https://example2.com/api/v2/"
Example #2
0
def test_regression_double_slashes():
    object_url = "http://example.com/api/v1/zaken/28dcfc90-2d26-4d4e-8261-a9202ee56185"
    client = Client.from_url(object_url)
    # prevents http request to fetch the schema
    client._schema = {
        "openapi": "3.0.0",
        "servers": [{"url": "/api/v1"}],
        "paths": {
            "/zaken/{zaak_uuid}/informatieobjecten": {
                "post": {"operationId": "zaakinformatieobject_create"}
            }
        },
    }
    pattern = get_operation_url(
        client.schema, "zaakinformatieobject_create", pattern_only=True
    )
    params = extract_params("{}/irrelevant".format(object_url), pattern)

    url = get_operation_url(
        client.schema, "zaakinformatieobject_create", base_url=client.base_url, **params
    )

    assert (
        url == "/api/v1/zaken/28dcfc90-2d26-4d4e-8261-a9202ee56185/informatieobjecten"
    )
Example #3
0
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()
Example #4
0
    def get_client(cls) -> Client:
        """
        Construct a client, prepared with the required auth.
        """
        config = cls.get_solo()

        if getattr(settings, "CUSTOM_CLIENT_FETCHER", None):
            client = import_string(settings.CUSTOM_CLIENT_FETCHER)(config.api_root)
            return client
        else:
            Client = import_string(settings.ZDS_CLIENT_CLASS)

            api_root = config.api_root
            if not api_root:
                raise ImproperlyConfigured(
                    f"Configure the API root in '{cls._meta.verbose_name}'"
                )

            if not api_root.endswith("/"):
                api_root = f"{api_root}/"

            client = Client.from_url(api_root)
            client.base_url = api_root
            client.auth = APICredential.get_auth(api_root)

            return client
Example #5
0
    def register(self) -> None:
        """
        Registers the webhook with the notification component.
        """
        dummy_detail_url = urljoin(self.config.api_root, f'foo/{uuid.uuid4()}')
        client = Client.from_url(dummy_detail_url)

        # This authentication is to create a subscription at the NC.
        client.auth = APICredential.get_auth(
            self.config.api_root, scopes=[SCOPE_NOTIFICATIES_CONSUMEREN_LABEL])

        # This authentication is for the NC to call us. Thus, it's *not* for
        # calling the NC to create a subscription.
        self_auth = ClientAuth(client_id=self.client_id,
                               secret=self.secret,
                               scopes=[SCOPE_NOTIFICATIES_PUBLICEREN_LABEL])
        data = {
            'callbackUrl':
            self.callback_url,
            'auth':
            self_auth.credentials()['Authorization'],
            'kanalen': [
                {
                    "naam": channel,
                    # FIXME: You need to be able to configure these.
                    "filters": {},
                } for channel in self.channels
            ],
        }

        # register the subscriber
        subscriber = client.create('abonnement', data=data)

        self._subscription = subscriber['url']
        self.save(update_fields=['_subscription'])
Example #6
0
def get_client(url: str, url_is_api_root=False) -> Optional[Client]:
    """
    Get a client instance for the given URL.

    If the setting CUSTOM_CLIENT_FETCHER is defined, then this callable is invoked.
    Otherwise we fall back on the default implementation.

    If no suitable client is found, ``None`` is returned.
    """
    custom_client_fetcher = getattr(settings, "CUSTOM_CLIENT_FETCHER", None)
    if custom_client_fetcher:
        client_getter = import_string(custom_client_fetcher)
        return client_getter(url)

    # default implementation
    Client = import_string(settings.ZDS_CLIENT_CLASS)

    if url_is_api_root and not url.endswith("/"):
        url = f"{url}/"

    client = Client.from_url(url)
    if client is None:
        return None

    APICredential = apps.get_model("vng_api_common", "APICredential")

    if url_is_api_root:
        client.base_url = url

    client.auth = APICredential.get_auth(url)
    return client
Example #7
0
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
Example #8
0
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 sync(relation: ObjectInformatieObject, operation: str):
    # build the URL of the informatieobject
    path = reverse('enkelvoudiginformatieobject-detail', kwargs={
        'version': settings.REST_FRAMEWORK['DEFAULT_VERSION'],
        'uuid': relation.informatieobject.uuid,
    })
    domain = Site.objects.get_current().domain
    protocol = 'https' if settings.IS_HTTPS else 'http'
    informatieobject_url = f'{protocol}://{domain}{path}'

    logger.info("Remote object: %s", relation.object)
    logger.info("Informatieobject: %s", informatieobject_url)

    # figure out which remote resource we need to interact with
    resource = f"{relation.object_type}informatieobject"
    client = Client.from_url(relation.object)

    try:
        pattern = get_operation_url(client.schema, f'{resource}_{operation}', pattern_only=True)
    except ValueError as exc:
        raise SyncError("Could not determine remote operation") from exc

    # we enforce in the standard that it's a subresource so that we can do this.
    # The real resource URL is extracted from the ``openapi.yaml`` based on
    # the operation
    params = extract_params(f"{relation.object}/irrelevant", pattern)

    try:
        operation_function = getattr(client, operation)
        operation_function(resource, {'informatieobject': informatieobject_url}, **params)
    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
Example #10
0
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
Example #11
0
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
Example #12
0
    def get_client(cls) -> Client:
        """
        Construct a client, prepared with the required auth.
        """
        config = cls.get_solo()
        Client = import_string(settings.ZDS_CLIENT_CLASS)

        api_root = config.api_root
        if not api_root:
            raise ImproperlyConfigured(
                f"Configure the API root in '{cls._meta.verbose_name}'")

        if not api_root.endswith('/'):
            api_root = f"{api_root}/"

        client = Client.from_url(api_root)
        client.base_url = api_root

        return client
Example #13
0
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
Example #14
0
def sync_create_vio(relation: VerzoekInformatieObject):
    operation = "create"

    # build the URL of the Verzoek
    path = reverse(
        "verzoek-detail",
        kwargs={
            "version": settings.REST_FRAMEWORK["DEFAULT_VERSION"],
            "uuid": relation.verzoek.uuid,
        },
    )
    domain = Site.objects.get_current().domain
    protocol = "https" if settings.IS_HTTPS else "http"
    verzoek_url = f"{protocol}://{domain}{path}"

    logger.info("Verzoek: %s", verzoek_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)

    # TODO?
    client.auth = APICredential.get_auth(relation.informatieobject)

    try:
        operation_function = getattr(client, operation)
        operation_function(
            resource,
            {
                "object": verzoek_url,
                "informatieobject": relation.informatieobject,
                "objectType": "verzoek",
            },
        )
    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
Example #15
0
def sync_delete_vio(relation: VerzoekInformatieObject):
    operation = "delete"

    # build the URL of the Verzoek
    path = reverse(
        "verzoek-detail",
        kwargs={
            "version": settings.REST_FRAMEWORK["DEFAULT_VERSION"],
            "uuid": relation.verzoek.uuid,
        },
    )
    domain = Site.objects.get_current().domain
    protocol = "https" if settings.IS_HTTPS else "http"
    verzoek_url = f"{protocol}://{domain}{path}"

    logger.info("Verzoek: %s", verzoek_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
    response = client.list(resource, query_params={"object": verzoek_url})
    try:
        relation_url = response[0]["url"]
    except IndexError as exc:
        msg = "No relations found in DRC for this Verzoek"
        logger.error(msg, exc_info=1)
        raise IndexError(msg) from exc

    try:
        operation_function = getattr(client, operation)
        operation_function(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
Example #16
0
def sync_create_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)

    try:
        client.create(
            resource,
            {
                "object": zaak_url,
                "informatieobject": relation.informatieobject,
                "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
Example #17
0
def test_client_from_detail_url(detail_url, expected_base_path):
    client = Client.from_url(detail_url)
    assert client.base_path == expected_base_path