예제 #1
0
    def handle(self, *args, **options):
        nrc_client = NotificationsConfig.get_client()

        kanaal_name = "test"
        Kanaal(kanaal_name, "test")

        data = {
            "kanaal": kanaal_name,
            "hoofdObject": "https://example.com",
            "resource": "test",
            "resourceUrl": "https://example.com",
            "actie": "create",
            "aanmaakdatum": "2019-01-01T12:00:00Z",
            "kenmerken": {},
        }

        try:
            nrc_client.create("notificaties", data)
            self.stdout.write(
                self.style.SUCCESS(
                    f"Notification successfully sent to {nrc_client.base_url}!"
                ))
        except Exception as e:
            self.stdout.write(
                self.style.ERROR(
                    f"Something went wrong while sending the notification to {nrc_client.base_url}"
                ))
            raise CommandError(e)
예제 #2
0
def resend_notification(notification: FailedNotification) -> None:
    """
    Resend a failed notification.

    The message is extracted from the failed notification log. If any resends
    fail, they are logged again with the same original logger, making them
    available for future retries.
    """
    assert notification.retried_at is None, "Can only resend not-retried notifications"
    config = NotificationsConfig.get_solo()
    client = config.get_client()

    try:
        client.create("notificaties", notification.message)
    except ClientError as error:
        notifs_logger.warning(
            "Could not deliver message to %s",
            client.base_url,
            exc_info=True,
            extra={
                "notification_msg": notification.message,
                "status_code": notification.status_code,
            },
        )
        raise ResendFailure from error
    finally:
        notification.retried_at = timezone.now()
        notification.save()
    def test_notification_config_inaccessible_create(self):
        conf = NotificationsConfig.get_solo()
        conf.api_root = "http://localhost:8001/api/v1/"
        conf.save()

        url = get_operation_url("zaak_create")
        zaaktype = ZaakTypeFactory.create(concept=False)
        zaaktype_url = reverse(zaaktype)
        data = {
            "zaaktype": f"http://testserver{zaaktype_url}",
            "vertrouwelijkheidaanduiding":
            VertrouwelijkheidsAanduiding.openbaar,
            "bronorganisatie": "517439943",
            "verantwoordelijkeOrganisatie": VERANTWOORDELIJKE_ORGANISATIE,
            "registratiedatum": "2012-01-13",
            "startdatum": "2012-01-13",
            "toelichting": "Een stel dronken toeristen speelt versterkte "
            "muziek af vanuit een gehuurde boot.",
            "zaakgeometrie": {
                "type": "Point",
                "coordinates": [4.910649523925713, 52.37240093589432],
            },
        }

        response = self.client.post(url, data, **ZAAK_WRITE_KWARGS)

        self.assertEqual(response.status_code,
                         status.HTTP_500_INTERNAL_SERVER_ERROR)
        self.assertFalse(Zaak.objects.exists())
        self.assertFalse(StatusLog.objects.exists())
예제 #4
0
    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

        # To use the mechanics in vng-api-common, we create a JWTSecret object
        # so we don't need to implement our own authentication layer for the
        # notification callback API.
        if self.callback_client_id and self.callback_secret:
            JWTSecret.objects.update_or_create(
                identifier=self.callback_client_id,
                defaults={
                    'secret': self.callback_secret,
                })

        # Create NotificationConfig to store the NC.
        notifications_config = NotificationsConfig.get_solo()
        if self.nc_base_url:
            notifications_config.api_root = self.nc_base_url
            notifications_config.client_id = self.nc_client_id or self.global_api_client_id
            notifications_config.secret = self.nc_secret or self.global_api_secret
            notifications_config.save()

        # Create Subscription based on details here with default channel and
        # topics.
        Subscription.objects.update_or_create(config=notifications_config,
                                              defaults={
                                                  'callback_url':
                                                  self.callback_url,
                                                  'client_id':
                                                  self.callback_client_id,
                                                  'secret':
                                                  self.callback_secret,
                                                  'channels': [
                                                      'zaken',
                                                  ]
                                              })
예제 #5
0
def _test_nrc_config() -> list:
    if not apps.is_installed("vng_api_common.notifications"):
        return []

    from vng_api_common.notifications.models import NotificationsConfig

    nrc_config = NotificationsConfig.get_solo()

    nrc_client = NotificationsConfig.get_client()

    has_nrc_auth = nrc_client.auth is not None

    checks = [
        (_("NRC"), nrc_config.api_root, nrc_config.api_root.endswith("/")),
        (
            _("Credentials for NRC"),
            _("Configured") if has_nrc_auth else _("Missing"),
            has_nrc_auth,
        ),
    ]

    # check if permissions in AC are fine
    if has_nrc_auth:
        error = False

        try:
            nrc_client.list("kanaal")
        except requests.ConnectionError:
            error = True
            message = _("Could not connect with NRC")
        except ClientError as exc:
            error = True
            message = _(
                "Cannot retrieve kanalen: HTTP {status_code} - {error_code}"
            ).format(status_code=exc.args[0]["status"],
                     error_code=exc.args[0]["code"])
        else:
            message = _("Can retrieve kanalen")

        checks.append(
            (_("NRC connection and authorizations"), message, not error))

    return checks
예제 #6
0
    def setUp(self):
        super().setUp()

        config = NotificationsConfig.get_solo()
        Service.objects.create(
            api_type=APITypes.nrc,
            api_root=config.api_root,
            client_id="test",
            secret="test",
            user_id="test",
            user_representation="Test",
        )
예제 #7
0
def test_register_webhook_success(request_with_middleware, *mocks):

    config = NotificationsConfig.get_solo()

    subscription = Subscription.objects.create(
        config=config,
        callback_url="https://example.com/callback",
        client_id="client_id",
        secret="secret",
        channels=["zaken"],
    )

    register_webhook(object, request_with_middleware,
                     Subscription.objects.all())

    messages = list(get_messages(request_with_middleware))

    assert len(messages) == 0

    subscription.refresh_from_db()
    assert subscription._subscription == "https://example.com/api/v1/abonnementen/1"
예제 #8
0
def test_register_webhook_client_error(request_with_middleware):

    config = NotificationsConfig.get_solo()

    Subscription.objects.create(
        config=config,
        callback_url="https://example.com/callback",
        client_id="client_id",
        secret="secret",
        channels=["zaken"],
    )

    with patch("zds_client.client.Client.create",
               side_effect=ClientError("exception")):
        register_webhook(object, request_with_middleware,
                         Subscription.objects.all())

    messages = list(get_messages(request_with_middleware))

    assert len(messages) == 1
    assert messages[0].message == _(
        "Something went wrong while registering subscription for {callback_url}: {e}"
    ).format(callback_url="https://example.com/callback", e="exception")
예제 #9
0
    def test_correct_credentials_used(self):
        svc, _ = Service.objects.update_or_create(
            api_root="https://open-notificaties.local/api/v1/",
            defaults=dict(
                label="NRC",
                api_type=APITypes.nrc,
                client_id="some-client-id",
                secret="some-secret",
                auth_type=AuthTypes.zgw,
            ),
        )
        config = NotificationsConfig.get_solo()
        config.api_root = svc.api_root
        config.save()

        with requests_mock.Mocker() as m:
            mock_service_oas_get(m, "nrc", url=svc.api_root)
            m.get("https://open-notificaties.local/api/v1/kanaal?naam=zaken",
                  json=[])
            m.post("https://open-notificaties.local/api/v1/kanaal",
                   status_code=201)

            call_command("register_kanaal", kanaal="zaken")

            # check for auth in the calls
            for request in m.request_history[1:]:
                with self.subTest(method=request.method, url=request.url):
                    self.assertIn("Authorization", request.headers)
                    token = request.headers["Authorization"].split(" ")[1]
                    try:
                        jwt.decode(token,
                                   key="some-secret",
                                   algorithms=["HS256"])
                    except Exception as exc:
                        self.fail(
                            "Not a vaid JWT in Authorization header: %s" % exc)
예제 #10
0
    def test_setup_configuration(self):
        openzaak_domain = "open-zaak.utrecht.nl"
        nrc_root = "https://open-notificaties.utrecht.nl/api/v1/"
        municipality = "Utrecht"
        openzaak_to_notif_secret = "12345"
        notif_to_openzaak_secret = "54321"

        call_command(
            "setup_configuration",
            openzaak_domain,
            nrc_root,
            municipality,
            openzaak_to_notif_secret,
            notif_to_openzaak_secret,
        )

        site = Site.objects.get_current()
        self.assertEqual(site.domain, openzaak_domain)
        self.assertEqual(site.name, f"Open Zaak {municipality}")

        notif_config = NotificationsConfig.get_solo()
        self.assertEqual(notif_config.api_root, nrc_root)

        api_credential = APICredential.objects.get()
        self.assertEqual(api_credential.api_root, nrc_root)
        self.assertEqual(
            api_credential.label,
            f"Open Notificaties {municipality}",
        )
        self.assertEqual(api_credential.client_id,
                         f"open-zaak-{municipality.lower()}")
        self.assertEqual(api_credential.secret, openzaak_to_notif_secret)
        self.assertEqual(api_credential.user_id,
                         f"open-zaak-{municipality.lower()}")
        self.assertEqual(api_credential.user_representation,
                         f"Open Zaak {municipality}")

        notif_api_jwtsecret_ac = JWTSecret.objects.get()
        self.assertEqual(
            notif_api_jwtsecret_ac.identifier,
            f"open-notificaties-{municipality.lower()}",
        )
        self.assertEqual(notif_api_jwtsecret_ac.secret,
                         notif_to_openzaak_secret)

        notif_api_applicatie_ac = Applicatie.objects.get(
            label=f"Open Notificaties {municipality}")
        self.assertEqual(notif_api_applicatie_ac.client_ids,
                         [notif_api_jwtsecret_ac.identifier])

        notif_api_autorisatie_ac = Autorisatie.objects.get(
            applicatie=notif_api_applicatie_ac)
        self.assertEqual(notif_api_autorisatie_ac.component, ComponentTypes.ac)
        self.assertEqual(notif_api_autorisatie_ac.scopes,
                         [SCOPE_AUTORISATIES_LEZEN.label])

        openzaak_applicatie_notif = Applicatie.objects.get(
            label=f"Open Zaak {municipality}")
        self.assertEqual(openzaak_applicatie_notif.client_ids,
                         [f"open-zaak-{municipality.lower()}"])

        openzaak_autorisatie_notif = Autorisatie.objects.get(
            applicatie=openzaak_applicatie_notif)
        self.assertEqual(openzaak_autorisatie_notif.component,
                         ComponentTypes.nrc)
        self.assertEqual(
            openzaak_autorisatie_notif.scopes,
            [
                SCOPE_NOTIFICATIES_CONSUMEREN_LABEL,
                SCOPE_NOTIFICATIES_PUBLICEREN_LABEL,
            ],
        )
예제 #11
0
    def handle(self, *args, **options):
        try:
            openzaak_domain = options["openzaak_domain"]
            notifications_api_root = options["notifications_api_root"]
            municipality = options["municipality"]
            openzaak_to_notif_secret = options["openzaak_to_notif_secret"]
            notif_to_openzaak_secret = options["notif_to_openzaak_secret"]

            # See: https://open-zaak.readthedocs.io/en/latest/installation/configuration.html#setting-the-domain
            site = Site.objects.get_current()
            site.domain = openzaak_domain
            site.name = f"Open Zaak {municipality}"
            site.save()

            # For the steps below, see:
            # https://open-zaak.readthedocs.io/en/latest/installation/configuration.html#open-zaak

            # Step 1
            notif_config = NotificationsConfig.get_solo()
            notif_config.api_root = notifications_api_root
            notif_config.save()

            # Step 2
            if not APICredential.objects.filter(
                api_root=notifications_api_root
            ).exists():
                APICredential.objects.create(
                    api_root=notifications_api_root,
                    label=f"Open Notificaties {municipality}",
                    client_id=f"open-zaak-{municipality.lower()}",
                    secret=openzaak_to_notif_secret,
                    user_id=f"open-zaak-{municipality.lower()}",
                    user_representation=f"Open Zaak {municipality}",
                )

            # Step 3
            notif_api_jwtsecret_ac = JWTSecret.objects.create(
                identifier=f"open-notificaties-{municipality.lower()}",
                secret=notif_to_openzaak_secret,
            )
            notif_api_applicatie_ac = Applicatie.objects.create(
                label=f"Open Notificaties {municipality}",
                client_ids=[notif_api_jwtsecret_ac.identifier],
            )
            Autorisatie.objects.create(
                applicatie=notif_api_applicatie_ac,
                component=ComponentTypes.ac,
                scopes=[SCOPE_AUTORISATIES_LEZEN],
            )

            # Step 4
            openzaak_applicatie_notif = Applicatie.objects.create(
                label=f"Open Zaak {municipality}",
                client_ids=[f"open-zaak-{municipality.lower()}"],
            )
            Autorisatie.objects.create(
                applicatie=openzaak_applicatie_notif,
                component=ComponentTypes.nrc,
                scopes=[
                    SCOPE_NOTIFICATIES_CONSUMEREN_LABEL,
                    SCOPE_NOTIFICATIES_PUBLICEREN_LABEL,
                ],
            )

            self.stdout.write(
                self.style.SUCCESS(
                    "Initial configuration for Open Zaak was setup successfully"
                )
            )
        except Exception as e:
            raise CommandError(
                f"Something went wrong while setting up initial configuration: {e}"
            )
예제 #12
0
def test_notificationsconfig_custom_client():
    config = NotificationsConfig.get_solo()
    client = config.get_client()
    assert client == "testclient"