commonground-api-common 2.6.5__tar.gz → 2.6.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/CHANGELOG.rst +17 -0
- {commonground_api_common-2.6.5/commonground_api_common.egg-info → commonground_api_common-2.6.7}/PKG-INFO +5 -5
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/README.rst +2 -2
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7/commonground_api_common.egg-info}/PKG-INFO +5 -5
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/commonground_api_common.egg-info/requires.txt +2 -2
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/setup.cfg +3 -3
- commonground_api_common-2.6.7/tests/test_jwt_decoding.py +231 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_validators.py +19 -0
- commonground_api_common-2.6.7/vng_api_common/__init__.py +1 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/middleware.py +53 -2
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/conf/api.py +5 -2
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/tests/auth.py +2 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/validators.py +4 -1
- commonground_api_common-2.6.5/tests/test_jwt_decoding.py +0 -56
- commonground_api_common-2.6.5/vng_api_common/__init__.py +0 -1
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/MANIFEST.in +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/bin/generate_schema +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/commonground_api_common.egg-info/SOURCES.txt +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/commonground_api_common.egg-info/dependency_links.txt +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/commonground_api_common.egg-info/not-zip-safe +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/commonground_api_common.egg-info/top_level.txt +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/pyproject.toml +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/setup.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_autorisatie_validation.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_cache_headers.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_cached_hyperlinkrelatedfields.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_check_query_params.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_checks.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_choices.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_configuration_steps_applicaties.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_configuration_steps_jwtsecrets.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_content_type_headers.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_field_extensions.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_filter_extension.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_filters.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_gegevensgroepen.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_get_resource.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_jwtsecrets.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_migrations.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_nested_serializer_validation.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_pagination.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_permissions.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_publish_validators.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_schema.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_serializer_extensions.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_serializer_fields.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_server_errors.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_utils.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_views.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/admin.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/api/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/api/permissions.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/api/serializers.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/api/urls.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/api/views.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/apps.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/admin.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/api/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/api/scopes.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/api/serializers.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/apps.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/audits.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0001_initial.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0002_auto_20190516_0830.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0003_auto_20190517_0844.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0004_auto_20190520_1238.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0005_auto_20190520_1450.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0006_audittrail_toelichting.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0007_auto_20190522_0916.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0008_audittrail_resource_weergave.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0009_auto_20190712_1643.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0010_audittrail_request_id.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0011_auto_20190918_1335.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0012_auto_20200619_0545.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0012_remove_audittrail_request_id.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0013_audittrail_logrecord_id.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0013_auto_20201207_0846.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0014_auto_20201221_0905.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0014_auto_20210323_1654.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0015_auto_20220318_1608.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0016_merge_20220607_0517.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0017_alter_audittrail_bron.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/0018_auto_20221212_0745.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/migrations/_operations.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/models.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/utils.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/audittrails/viewsets.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/admin.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0001_initial.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0002_authorizationsconfig.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0003_auto_20190502_0409.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0004_auto_20190503_0941.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0005_auto_20190506_0842.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0006_auto_20190506_0901.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0007_auto_20190506_1212.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0008_auto_20190712_1541.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0009_update_enums.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0010_auto_20190712_1643.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0011_auto_20191114_0728.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0012_auto_20200619_0545.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0013_auto_20201207_0846.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0014_auto_20201221_0905.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0015_auto_20220318_1608.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0016_remove_authorizationsconfig_api_root_and_more.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/0017_alter_applicatie_client_ids_and_more.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/migrations/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/models.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/serializers.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/utils.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/authorizations/validators.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/caching/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/caching/decorators.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/caching/etags.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/caching/introspection.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/caching/models.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/caching/registry.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/caching/signals.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/checks.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/choices.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/client.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/compat.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/conf/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/constants.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/contrib/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/contrib/setup_configuration/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/contrib/setup_configuration/models.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/contrib/setup_configuration/steps.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/db/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/db/operations.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/decorators.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/descriptors.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/doc.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/exception_handling.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/exceptions.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/extensions/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/extensions/file.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/extensions/gegevensgroep.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/extensions/geojson.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/extensions/hyperlink.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/extensions/polymorphic.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/extensions/query.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/fields.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/filters.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/filters_backend.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/filtersets.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/generators.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/geo.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/locale/nl/LC_MESSAGES/django.mo +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/locale/nl/LC_MESSAGES/django.po +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/middleware.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/migrations/0001_initial.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/migrations/0002_apicredential.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/migrations/0003_auto_20190417_1145.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/migrations/0004_auto_20190517_0903.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/migrations/0005_auto_20190614_1346.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/migrations/0006_delete_apicredential.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/migrations/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/mocks.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/models.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/api/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/api/urls.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/api/views.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/apps.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/handlers.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/migrations/0001_initial.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/migrations/0002_subscription__subscription.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/migrations/0003_auto_20190319_1048.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/migrations/0004_auto_20190325_1313.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/migrations/0005_fix_default_nrc.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/migrations/0006_auto_20190417_1142.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/migrations/0007_auto_20190429_1442.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/migrations/0008_auto_20190502_0415.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/migrations/0009_auto_20190729_0427.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/migrations/0010_auto_20220704_1419.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/migrations/0011_remove_subscription_config_and_more.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/notifications/migrations/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/oas.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/pagination.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/permissions.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/polymorphism.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/routers.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/schema.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/scopes.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/search.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/serializers.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/css/admin/admin_overrides.css +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/css/screen.css +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/ico/favicon.png +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/img/vng.svg +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/LICENSE.txt +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/css/all.css +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/css/all.min.css +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-brands-400.eot +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-brands-400.svg +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-brands-400.ttf +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-brands-400.woff +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-brands-400.woff2 +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-regular-400.eot +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-regular-400.svg +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-regular-400.ttf +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-regular-400.woff +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-regular-400.woff2 +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-solid-900.eot +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-solid-900.svg +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-solid-900.ttf +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-solid-900.woff +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-solid-900.woff2 +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/templates/vng_api_common/admin/base_site.html +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/templates/vng_api_common/includes/kanalen_card.html +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/templates/vng_api_common/index.html +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/templates/vng_api_common/master.html +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/templates/vng_api_common/ref/error_detail.html +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/templates/vng_api_common/ref/scopes.html +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/templates/vng_api_common/view_config.html +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/templatetags/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/templatetags/vng_api_common.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/tests/__init__.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/tests/caching.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/tests/schema.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/tests/urls.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/urls.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/utils.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/version.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/views.py +0 -0
- {commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/viewsets.py +0 -0
@@ -2,6 +2,23 @@
|
|
2
2
|
Change history
|
3
3
|
==============
|
4
4
|
|
5
|
+
2.6.7 (2025-06-30)
|
6
|
+
------------------
|
7
|
+
|
8
|
+
**Bugfixes**
|
9
|
+
|
10
|
+
* [#103] Fix 500 error that occurred with ``iat`` in future, log a warning
|
11
|
+
* Add JWT expiry validation based on ``iat``
|
12
|
+
|
13
|
+
**Maintenance**
|
14
|
+
|
15
|
+
* Upgrade PyJWT to 2.10.1
|
16
|
+
|
17
|
+
2.6.6 (2025-06-04)
|
18
|
+
------------------
|
19
|
+
|
20
|
+
* [open-zaak/open-zaak#635] Rename JWT_LEEWAY setting to TIME_LEEWAY and add it to UntilNowValidator
|
21
|
+
|
5
22
|
2.6.5 (2025-05-27)
|
6
23
|
------------------
|
7
24
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: commonground-api-common
|
3
|
-
Version: 2.6.
|
3
|
+
Version: 2.6.7
|
4
4
|
Summary: Commonground API tooling
|
5
5
|
Home-page: https://github.com/maykinmedia/commonground-api-common
|
6
6
|
Author: Maykin Media, VNG-Realisatie
|
@@ -32,7 +32,7 @@ Requires-Dist: iso639-lang
|
|
32
32
|
Requires-Dist: notifications-api-common>=0.3.1
|
33
33
|
Requires-Dist: zgw-consumers>=0.35.1
|
34
34
|
Requires-Dist: oyaml
|
35
|
-
Requires-Dist: PyJWT>=2.
|
35
|
+
Requires-Dist: PyJWT>=2.10.1
|
36
36
|
Requires-Dist: requests
|
37
37
|
Requires-Dist: coreapi
|
38
38
|
Requires-Dist: ape-pie
|
@@ -48,7 +48,7 @@ Requires-Dist: psycopg2; extra == "tests"
|
|
48
48
|
Requires-Dist: pytest; extra == "tests"
|
49
49
|
Requires-Dist: pytest-django; extra == "tests"
|
50
50
|
Requires-Dist: pytest-dotenv; extra == "tests"
|
51
|
-
Requires-Dist: pytest-factoryboy; extra == "tests"
|
51
|
+
Requires-Dist: pytest-factoryboy>=2.8.0; extra == "tests"
|
52
52
|
Requires-Dist: tox; extra == "tests"
|
53
53
|
Requires-Dist: ruff; extra == "tests"
|
54
54
|
Requires-Dist: requests-mock; extra == "tests"
|
@@ -76,7 +76,7 @@ Commonground-API-common - Tooling voor RESTful APIs
|
|
76
76
|
===================================================
|
77
77
|
|
78
78
|
|
79
|
-
:Version: 2.6.
|
79
|
+
:Version: 2.6.7
|
80
80
|
:Source: https://github.com/maykinmedia/commonground-api-common
|
81
81
|
:PythonVersion: 3.12
|
82
82
|
|
@@ -109,7 +109,7 @@ Features
|
|
109
109
|
* Niet-negatieve waarde validator
|
110
110
|
* Alfanumerieke waarde (zonder diacritics)
|
111
111
|
* URL-validator (test dat URL bestaat) met pluggable link-checker
|
112
|
-
* ``UntilNowValidator`` - valideer datetimes tot en met *nu*.
|
112
|
+
* ``UntilNowValidator`` - valideer datetimes tot en met *nu*. (Via de TIME_LEEWAY setting kan speling worden toegevoegd)
|
113
113
|
* ``UniekeIdentificatieValidator`` (in combinatie met organisatie)
|
114
114
|
* ``InformatieObjectUniqueValidator`` om te valideren dat M2M entries
|
115
115
|
slechts eenmalig voorkomen
|
@@ -3,7 +3,7 @@ Commonground-API-common - Tooling voor RESTful APIs
|
|
3
3
|
===================================================
|
4
4
|
|
5
5
|
|
6
|
-
:Version: 2.6.
|
6
|
+
:Version: 2.6.7
|
7
7
|
:Source: https://github.com/maykinmedia/commonground-api-common
|
8
8
|
:PythonVersion: 3.12
|
9
9
|
|
@@ -36,7 +36,7 @@ Features
|
|
36
36
|
* Niet-negatieve waarde validator
|
37
37
|
* Alfanumerieke waarde (zonder diacritics)
|
38
38
|
* URL-validator (test dat URL bestaat) met pluggable link-checker
|
39
|
-
* ``UntilNowValidator`` - valideer datetimes tot en met *nu*.
|
39
|
+
* ``UntilNowValidator`` - valideer datetimes tot en met *nu*. (Via de TIME_LEEWAY setting kan speling worden toegevoegd)
|
40
40
|
* ``UniekeIdentificatieValidator`` (in combinatie met organisatie)
|
41
41
|
* ``InformatieObjectUniqueValidator`` om te valideren dat M2M entries
|
42
42
|
slechts eenmalig voorkomen
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: commonground-api-common
|
3
|
-
Version: 2.6.
|
3
|
+
Version: 2.6.7
|
4
4
|
Summary: Commonground API tooling
|
5
5
|
Home-page: https://github.com/maykinmedia/commonground-api-common
|
6
6
|
Author: Maykin Media, VNG-Realisatie
|
@@ -32,7 +32,7 @@ Requires-Dist: iso639-lang
|
|
32
32
|
Requires-Dist: notifications-api-common>=0.3.1
|
33
33
|
Requires-Dist: zgw-consumers>=0.35.1
|
34
34
|
Requires-Dist: oyaml
|
35
|
-
Requires-Dist: PyJWT>=2.
|
35
|
+
Requires-Dist: PyJWT>=2.10.1
|
36
36
|
Requires-Dist: requests
|
37
37
|
Requires-Dist: coreapi
|
38
38
|
Requires-Dist: ape-pie
|
@@ -48,7 +48,7 @@ Requires-Dist: psycopg2; extra == "tests"
|
|
48
48
|
Requires-Dist: pytest; extra == "tests"
|
49
49
|
Requires-Dist: pytest-django; extra == "tests"
|
50
50
|
Requires-Dist: pytest-dotenv; extra == "tests"
|
51
|
-
Requires-Dist: pytest-factoryboy; extra == "tests"
|
51
|
+
Requires-Dist: pytest-factoryboy>=2.8.0; extra == "tests"
|
52
52
|
Requires-Dist: tox; extra == "tests"
|
53
53
|
Requires-Dist: ruff; extra == "tests"
|
54
54
|
Requires-Dist: requests-mock; extra == "tests"
|
@@ -76,7 +76,7 @@ Commonground-API-common - Tooling voor RESTful APIs
|
|
76
76
|
===================================================
|
77
77
|
|
78
78
|
|
79
|
-
:Version: 2.6.
|
79
|
+
:Version: 2.6.7
|
80
80
|
:Source: https://github.com/maykinmedia/commonground-api-common
|
81
81
|
:PythonVersion: 3.12
|
82
82
|
|
@@ -109,7 +109,7 @@ Features
|
|
109
109
|
* Niet-negatieve waarde validator
|
110
110
|
* Alfanumerieke waarde (zonder diacritics)
|
111
111
|
* URL-validator (test dat URL bestaat) met pluggable link-checker
|
112
|
-
* ``UntilNowValidator`` - valideer datetimes tot en met *nu*.
|
112
|
+
* ``UntilNowValidator`` - valideer datetimes tot en met *nu*. (Via de TIME_LEEWAY setting kan speling worden toegevoegd)
|
113
113
|
* ``UniekeIdentificatieValidator`` (in combinatie met organisatie)
|
114
114
|
* ``InformatieObjectUniqueValidator`` om te valideren dat M2M entries
|
115
115
|
slechts eenmalig voorkomen
|
@@ -10,7 +10,7 @@ iso639-lang
|
|
10
10
|
notifications-api-common>=0.3.1
|
11
11
|
zgw-consumers>=0.35.1
|
12
12
|
oyaml
|
13
|
-
PyJWT>=2.
|
13
|
+
PyJWT>=2.10.1
|
14
14
|
requests
|
15
15
|
coreapi
|
16
16
|
ape-pie
|
@@ -47,7 +47,7 @@ psycopg2
|
|
47
47
|
pytest
|
48
48
|
pytest-django
|
49
49
|
pytest-dotenv
|
50
|
-
pytest-factoryboy
|
50
|
+
pytest-factoryboy>=2.8.0
|
51
51
|
tox
|
52
52
|
ruff
|
53
53
|
requests-mock
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[metadata]
|
2
2
|
name = commonground-api-common
|
3
|
-
version = 2.6.
|
3
|
+
version = 2.6.7
|
4
4
|
description = Commonground API tooling
|
5
5
|
long_description = file: README.rst
|
6
6
|
url = https://github.com/maykinmedia/commonground-api-common
|
@@ -42,7 +42,7 @@ install_requires =
|
|
42
42
|
notifications-api-common>=0.3.1
|
43
43
|
zgw-consumers>=0.35.1
|
44
44
|
oyaml
|
45
|
-
PyJWT>=2.
|
45
|
+
PyJWT>=2.10.1
|
46
46
|
requests
|
47
47
|
coreapi
|
48
48
|
ape-pie
|
@@ -74,7 +74,7 @@ tests =
|
|
74
74
|
pytest
|
75
75
|
pytest-django
|
76
76
|
pytest-dotenv
|
77
|
-
pytest-factoryboy
|
77
|
+
pytest-factoryboy>=2.8.0
|
78
78
|
tox
|
79
79
|
ruff
|
80
80
|
requests-mock
|
@@ -0,0 +1,231 @@
|
|
1
|
+
from datetime import datetime
|
2
|
+
|
3
|
+
import jwt
|
4
|
+
import pytest
|
5
|
+
from freezegun import freeze_time
|
6
|
+
from rest_framework.exceptions import PermissionDenied
|
7
|
+
|
8
|
+
from vng_api_common.authorizations.middleware import JWTAuth
|
9
|
+
from vng_api_common.models import JWTSecret
|
10
|
+
|
11
|
+
|
12
|
+
@pytest.mark.django_db
|
13
|
+
def test_jwt_decode_ok():
|
14
|
+
secret = "secret"
|
15
|
+
JWTSecret.objects.create(identifier="client", secret=secret)
|
16
|
+
timestamp = int(datetime.now().timestamp())
|
17
|
+
token = jwt.encode(
|
18
|
+
{"client_id": "client", "iat": timestamp}, secret, algorithm="HS256"
|
19
|
+
)
|
20
|
+
|
21
|
+
auth = JWTAuth(token)
|
22
|
+
|
23
|
+
payload = auth.payload
|
24
|
+
assert auth.client_id == "client"
|
25
|
+
assert payload == {"client_id": "client", "iat": timestamp}
|
26
|
+
|
27
|
+
|
28
|
+
@pytest.mark.django_db
|
29
|
+
def test_jwt_decode_missing_iat():
|
30
|
+
secret = "secret"
|
31
|
+
JWTSecret.objects.create(identifier="client", secret=secret)
|
32
|
+
token = jwt.encode({"client_id": "client"}, secret, algorithm="HS256")
|
33
|
+
|
34
|
+
auth = JWTAuth(token)
|
35
|
+
|
36
|
+
with pytest.raises(PermissionDenied):
|
37
|
+
auth.payload
|
38
|
+
|
39
|
+
|
40
|
+
@pytest.mark.django_db
|
41
|
+
def test_jwt_decode_str_iat():
|
42
|
+
JWTSecret.objects.create(identifier="client", secret="secret")
|
43
|
+
payload = {
|
44
|
+
"client_id": "client",
|
45
|
+
"iat": "timestamp",
|
46
|
+
}
|
47
|
+
token = jwt.encode(payload, "secret", algorithm="HS256")
|
48
|
+
|
49
|
+
auth = JWTAuth(token)
|
50
|
+
|
51
|
+
with pytest.raises(PermissionDenied):
|
52
|
+
auth.payload
|
53
|
+
|
54
|
+
|
55
|
+
@pytest.mark.django_db
|
56
|
+
@freeze_time("2021-08-23T14:20:00")
|
57
|
+
def test_nbf_validated():
|
58
|
+
JWTSecret.objects.create(identifier="client", secret="secret")
|
59
|
+
timestamp = int(datetime.now().timestamp())
|
60
|
+
payload = {
|
61
|
+
"client_id": "client",
|
62
|
+
"iat": timestamp,
|
63
|
+
"nbf": timestamp + 1, # 1 second "later" than current time
|
64
|
+
}
|
65
|
+
token = jwt.encode(payload, "secret", algorithm="HS256")
|
66
|
+
|
67
|
+
auth = JWTAuth(token)
|
68
|
+
|
69
|
+
with pytest.raises(PermissionDenied):
|
70
|
+
auth.payload
|
71
|
+
|
72
|
+
|
73
|
+
@pytest.mark.django_db
|
74
|
+
@freeze_time("2021-08-23T14:20:00")
|
75
|
+
def test_nbf_validated_with_leeway(settings):
|
76
|
+
settings.TIME_LEEWAY = 3
|
77
|
+
JWTSecret.objects.create(identifier="client", secret="secret")
|
78
|
+
timestamp = int(datetime.now().timestamp())
|
79
|
+
payload = {
|
80
|
+
"client_id": "client",
|
81
|
+
"iat": timestamp,
|
82
|
+
"nbf": timestamp + 1, # 1 second "later" than current time
|
83
|
+
}
|
84
|
+
token = jwt.encode(payload, "secret", algorithm="HS256")
|
85
|
+
|
86
|
+
auth = JWTAuth(token)
|
87
|
+
|
88
|
+
assert auth.payload == payload
|
89
|
+
|
90
|
+
|
91
|
+
@pytest.mark.django_db
|
92
|
+
@freeze_time("2021-08-23T14:20:00")
|
93
|
+
def test_nbf_validated_with_leeway_not_enough(settings):
|
94
|
+
settings.TIME_LEEWAY = 3
|
95
|
+
JWTSecret.objects.create(identifier="client", secret="secret")
|
96
|
+
timestamp = int(datetime.now().timestamp())
|
97
|
+
payload = {
|
98
|
+
"client_id": "client",
|
99
|
+
"iat": timestamp,
|
100
|
+
"nbf": timestamp + 10, # 1 second "later" than current time
|
101
|
+
}
|
102
|
+
token = jwt.encode(payload, "secret", algorithm="HS256")
|
103
|
+
|
104
|
+
auth = JWTAuth(token)
|
105
|
+
|
106
|
+
with pytest.raises(PermissionDenied):
|
107
|
+
auth.payload
|
108
|
+
|
109
|
+
|
110
|
+
@pytest.mark.django_db
|
111
|
+
@freeze_time("2021-08-23T14:20:00")
|
112
|
+
def test_iat_validated():
|
113
|
+
"""jwt iat in future only logs a warning"""
|
114
|
+
JWTSecret.objects.create(identifier="client", secret="secret")
|
115
|
+
timestamp = int(datetime.now().timestamp())
|
116
|
+
payload = {
|
117
|
+
"client_id": "client",
|
118
|
+
"iat": timestamp + 1, # 1 second "later" than current time
|
119
|
+
}
|
120
|
+
token = jwt.encode(payload, "secret", algorithm="HS256")
|
121
|
+
|
122
|
+
auth = JWTAuth(token)
|
123
|
+
|
124
|
+
assert auth.payload == payload
|
125
|
+
|
126
|
+
|
127
|
+
@pytest.mark.django_db
|
128
|
+
@freeze_time("2021-08-23T14:20:00")
|
129
|
+
def test_iat_validated_with_leeway(settings):
|
130
|
+
settings.TIME_LEEWAY = 3
|
131
|
+
JWTSecret.objects.create(identifier="client", secret="secret")
|
132
|
+
timestamp = int(datetime.now().timestamp())
|
133
|
+
payload = {
|
134
|
+
"client_id": "client",
|
135
|
+
"iat": timestamp + 1, # 1 second "later" than current time
|
136
|
+
}
|
137
|
+
token = jwt.encode(payload, "secret", algorithm="HS256")
|
138
|
+
|
139
|
+
auth = JWTAuth(token)
|
140
|
+
|
141
|
+
assert auth.payload == payload
|
142
|
+
|
143
|
+
|
144
|
+
@pytest.mark.django_db
|
145
|
+
@freeze_time("2021-08-23T14:20:00")
|
146
|
+
def test_iat_validated_with_leeway_not_enough(settings):
|
147
|
+
"""jwt iat in future only logs a warning"""
|
148
|
+
settings.TIME_LEEWAY = 3
|
149
|
+
JWTSecret.objects.create(identifier="client", secret="secret")
|
150
|
+
timestamp = int(datetime.now().timestamp())
|
151
|
+
payload = {
|
152
|
+
"client_id": "client",
|
153
|
+
"iat": timestamp + 10, # 1 second "later" than current time
|
154
|
+
}
|
155
|
+
token = jwt.encode(payload, "secret", algorithm="HS256")
|
156
|
+
|
157
|
+
auth = JWTAuth(token)
|
158
|
+
|
159
|
+
assert auth.payload == payload
|
160
|
+
|
161
|
+
|
162
|
+
@pytest.mark.django_db
|
163
|
+
@freeze_time("2021-08-23T14:20:00")
|
164
|
+
def test_exp_ok():
|
165
|
+
JWTSecret.objects.create(identifier="client", secret="secret")
|
166
|
+
timestamp = int(datetime.now().timestamp())
|
167
|
+
payload = {"client_id": "client", "iat": timestamp}
|
168
|
+
token = jwt.encode(payload, "secret", algorithm="HS256")
|
169
|
+
|
170
|
+
auth = JWTAuth(token)
|
171
|
+
|
172
|
+
assert auth.payload == payload
|
173
|
+
|
174
|
+
|
175
|
+
@pytest.mark.django_db
|
176
|
+
@freeze_time("2021-08-23T14:20:00")
|
177
|
+
def test_exp_within_exp_setting():
|
178
|
+
JWTSecret.objects.create(identifier="client", secret="secret")
|
179
|
+
timestamp = int(datetime.now().timestamp())
|
180
|
+
payload = {"client_id": "client", "iat": timestamp - 1000}
|
181
|
+
token = jwt.encode(payload, "secret", algorithm="HS256")
|
182
|
+
|
183
|
+
auth = JWTAuth(token)
|
184
|
+
|
185
|
+
assert auth.payload == payload
|
186
|
+
|
187
|
+
|
188
|
+
@pytest.mark.django_db
|
189
|
+
@freeze_time("2021-08-23T14:20:00")
|
190
|
+
def test_exp_validated(settings):
|
191
|
+
settings.JWT_EXPIRY = 3600
|
192
|
+
JWTSecret.objects.create(identifier="client", secret="secret")
|
193
|
+
timestamp = int(datetime.now().timestamp())
|
194
|
+
payload = {"client_id": "client", "iat": timestamp - 3601}
|
195
|
+
token = jwt.encode(payload, "secret", algorithm="HS256")
|
196
|
+
|
197
|
+
auth = JWTAuth(token)
|
198
|
+
|
199
|
+
with pytest.raises(PermissionDenied):
|
200
|
+
auth.payload
|
201
|
+
|
202
|
+
|
203
|
+
@pytest.mark.django_db
|
204
|
+
@freeze_time("2021-08-23T14:20:00")
|
205
|
+
def test_exp_validated_with_leeway(settings):
|
206
|
+
settings.JWT_EXPIRY = 3600
|
207
|
+
settings.TIME_LEEWAY = 5
|
208
|
+
JWTSecret.objects.create(identifier="client", secret="secret")
|
209
|
+
timestamp = int(datetime.now().timestamp())
|
210
|
+
payload = {"client_id": "client", "iat": timestamp - 3603}
|
211
|
+
token = jwt.encode(payload, "secret", algorithm="HS256")
|
212
|
+
|
213
|
+
auth = JWTAuth(token)
|
214
|
+
|
215
|
+
assert auth.payload == payload
|
216
|
+
|
217
|
+
|
218
|
+
@pytest.mark.django_db
|
219
|
+
@freeze_time("2021-08-23T14:20:00")
|
220
|
+
def test_exp_validated_with_leeway_not_enough(settings):
|
221
|
+
settings.JWT_EXPIRY = 3600
|
222
|
+
settings.TIME_LEEWAY = 5
|
223
|
+
JWTSecret.objects.create(identifier="client", secret="secret")
|
224
|
+
timestamp = int(datetime.now().timestamp())
|
225
|
+
payload = {"client_id": "client", "iat": timestamp - 3610}
|
226
|
+
token = jwt.encode(payload, "secret", algorithm="HS256")
|
227
|
+
|
228
|
+
auth = JWTAuth(token)
|
229
|
+
|
230
|
+
with pytest.raises(PermissionDenied):
|
231
|
+
auth.payload
|
@@ -1,10 +1,14 @@
|
|
1
|
+
from datetime import datetime, timezone
|
2
|
+
|
1
3
|
from django.core.exceptions import ValidationError
|
2
4
|
|
3
5
|
import pytest
|
6
|
+
from freezegun import freeze_time
|
4
7
|
|
5
8
|
from vng_api_common.validators import (
|
6
9
|
AlphanumericExcludingDiacritic,
|
7
10
|
BaseIdentifierValidator,
|
11
|
+
UntilNowValidator,
|
8
12
|
validate_bsn,
|
9
13
|
validate_rsin,
|
10
14
|
)
|
@@ -104,3 +108,18 @@ def test_invalid_rsin():
|
|
104
108
|
with pytest.raises(ValidationError) as error:
|
105
109
|
validate_rsin("12345678") # validate_length
|
106
110
|
assert "Waarde moet 9 tekens lang zijn" in str(error.value)
|
111
|
+
|
112
|
+
|
113
|
+
@freeze_time("2021-08-23T14:20:00")
|
114
|
+
def test_invalid_date():
|
115
|
+
validator = UntilNowValidator()
|
116
|
+
with pytest.raises(ValidationError) as error:
|
117
|
+
validator(datetime(2021, 8, 23, 14, 20, 4, tzinfo=timezone.utc))
|
118
|
+
assert "Ensure this value is not in the future." in str(error.value)
|
119
|
+
|
120
|
+
|
121
|
+
@freeze_time("2021-08-23T14:20:00")
|
122
|
+
def test_invalid_date_with_leeway(settings):
|
123
|
+
settings.TIME_LEEWAY = 5
|
124
|
+
validator = UntilNowValidator()
|
125
|
+
validator(datetime(2021, 8, 23, 14, 20, 4, tzinfo=timezone.utc))
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "2.6.7"
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import logging
|
2
|
+
import time
|
2
3
|
from typing import Any, Dict, Iterable, List, Optional
|
3
4
|
|
4
5
|
from django.conf import settings
|
@@ -108,7 +109,7 @@ class JWTAuth:
|
|
108
109
|
self.encoded,
|
109
110
|
algorithms=["HS256"],
|
110
111
|
options={"verify_signature": False},
|
111
|
-
leeway=settings.
|
112
|
+
leeway=settings.TIME_LEEWAY,
|
112
113
|
)
|
113
114
|
except jwt.DecodeError:
|
114
115
|
logger.info("Invalid JWT encountered")
|
@@ -146,13 +147,32 @@ class JWTAuth:
|
|
146
147
|
self.encoded,
|
147
148
|
key,
|
148
149
|
algorithms=["HS256"],
|
149
|
-
leeway=settings.
|
150
|
+
leeway=settings.TIME_LEEWAY,
|
151
|
+
options={
|
152
|
+
"require": ["iat"],
|
153
|
+
"verify_iat": False,
|
154
|
+
}, # iat is validated in _check_jwt_expiry
|
150
155
|
)
|
151
156
|
except jwt.InvalidSignatureError:
|
152
157
|
logger.exception("Invalid signature - possible payload tampering?")
|
153
158
|
raise PermissionDenied(
|
154
159
|
"Client credentials zijn niet geldig", code="invalid-jwt-signature"
|
155
160
|
)
|
161
|
+
except jwt.MissingRequiredClaimError as exc:
|
162
|
+
msg = "Missing required {} claim".format(exc.claim)
|
163
|
+
logger.exception(msg)
|
164
|
+
raise PermissionDenied(
|
165
|
+
_(msg),
|
166
|
+
code="jwt-missing-{}-claim".format(exc.claim),
|
167
|
+
)
|
168
|
+
except jwt.PyJWTError as exc:
|
169
|
+
logger.exception("Invalid JWT encountered")
|
170
|
+
raise PermissionDenied(
|
171
|
+
_("JWT did not validate"),
|
172
|
+
code="jwt-{}".format(type(exc).__name__.lower()),
|
173
|
+
)
|
174
|
+
|
175
|
+
self._check_jwt_expiry(payload)
|
156
176
|
|
157
177
|
self._payload = payload
|
158
178
|
|
@@ -164,6 +184,37 @@ class JWTAuth:
|
|
164
184
|
return None
|
165
185
|
return self.payload["client_id"]
|
166
186
|
|
187
|
+
def _check_jwt_expiry(self, payload: Dict[str, Any]) -> None:
|
188
|
+
"""
|
189
|
+
Verify that the token was issued recently enough.
|
190
|
+
|
191
|
+
The Django settings define how long a JWT is considered to be valid. Adding
|
192
|
+
that duration to the issued-at claim determines the upper limit for token
|
193
|
+
validity.
|
194
|
+
"""
|
195
|
+
iat = payload.get("iat")
|
196
|
+
|
197
|
+
try:
|
198
|
+
iat = int(iat)
|
199
|
+
except ValueError:
|
200
|
+
raise PermissionDenied(_("The iat claim must be an integer."))
|
201
|
+
|
202
|
+
current_timestamp = time.time()
|
203
|
+
difference = current_timestamp - iat
|
204
|
+
|
205
|
+
if difference < -settings.TIME_LEEWAY:
|
206
|
+
logger.warning(
|
207
|
+
"The JWT used for this request is not valid yet, the `iat` claim is "
|
208
|
+
"newer than the current time stamp. You may want to check the clock drift "
|
209
|
+
"on the Open Zaak server and/or tweak the `TIME_LEEWAY` setting.",
|
210
|
+
extra={"payload": payload},
|
211
|
+
)
|
212
|
+
|
213
|
+
if difference >= (settings.JWT_EXPIRY + settings.TIME_LEEWAY):
|
214
|
+
raise PermissionDenied(
|
215
|
+
_("The JWT used for this request is expired"), code="jwt-expired"
|
216
|
+
)
|
217
|
+
|
167
218
|
def filter_vertrouwelijkheidaanduiding(self, base: QuerySet, value) -> QuerySet:
|
168
219
|
if value is None:
|
169
220
|
return base
|
@@ -8,7 +8,8 @@ __all__ = [
|
|
8
8
|
"GEMMA_URL_INFORMATIEMODEL_VERSIE",
|
9
9
|
"GEMMA_URL_INFORMATIEMODEL",
|
10
10
|
"GEMMA_URL_TEMPLATE",
|
11
|
-
"
|
11
|
+
"TIME_LEEWAY",
|
12
|
+
"JWT_EXPIRY",
|
12
13
|
"JWT_SPECTACULAR_SETTINGS",
|
13
14
|
"LINK_FETCHER",
|
14
15
|
"NOTIFICATIONS_DISABLED",
|
@@ -95,6 +96,8 @@ vng_repo = "VNG-Realisatie/vng-api-common"
|
|
95
96
|
vng_branch = "ref-responses"
|
96
97
|
COMMON_SPEC = f"https://raw.githubusercontent.com/{vng_repo}/feature/{vng_branch}/vng_api_common/schemas/common.yaml"
|
97
98
|
|
98
|
-
|
99
|
+
TIME_LEEWAY = 0 # default in PyJWT
|
100
|
+
|
101
|
+
JWT_EXPIRY = 3600
|
99
102
|
|
100
103
|
COMMONGROUND_API_COMMON_GET_DOMAIN = "vng_api_common.utils.get_site_domain"
|
{commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/vng_api_common/validators.py
RENAMED
@@ -1,6 +1,7 @@
|
|
1
1
|
import json
|
2
2
|
import logging
|
3
3
|
import re
|
4
|
+
from datetime import timedelta
|
4
5
|
from typing import Callable
|
5
6
|
|
6
7
|
from django.conf import settings
|
@@ -277,6 +278,8 @@ class UntilNowValidator:
|
|
277
278
|
Validate a datetime to not be in the future.
|
278
279
|
|
279
280
|
This means that `now` is included.
|
281
|
+
|
282
|
+
Some leeway can be added with the TIME_LEEWAY setting.
|
280
283
|
"""
|
281
284
|
|
282
285
|
message = _("Ensure this value is not in the future.")
|
@@ -284,7 +287,7 @@ class UntilNowValidator:
|
|
284
287
|
|
285
288
|
@property
|
286
289
|
def limit_value(self):
|
287
|
-
return timezone.now()
|
290
|
+
return timezone.now() + timedelta(seconds=settings.TIME_LEEWAY)
|
288
291
|
|
289
292
|
def __call__(self, value):
|
290
293
|
if value > self.limit_value:
|
@@ -1,56 +0,0 @@
|
|
1
|
-
from datetime import datetime
|
2
|
-
|
3
|
-
import jwt
|
4
|
-
import pytest
|
5
|
-
from freezegun import freeze_time
|
6
|
-
from jwt import ImmatureSignatureError
|
7
|
-
|
8
|
-
from vng_api_common.authorizations.middleware import JWTAuth
|
9
|
-
from vng_api_common.models import JWTSecret
|
10
|
-
|
11
|
-
|
12
|
-
@pytest.mark.django_db
|
13
|
-
def test_jwt_decode_ok():
|
14
|
-
secret = "secret"
|
15
|
-
JWTSecret.objects.create(identifier="client", secret=secret)
|
16
|
-
token = jwt.encode({"client_id": "client"}, secret, algorithm="HS256")
|
17
|
-
|
18
|
-
auth = JWTAuth(token)
|
19
|
-
|
20
|
-
payload = auth.payload
|
21
|
-
assert auth.client_id == "client"
|
22
|
-
assert payload == {"client_id": "client"}
|
23
|
-
|
24
|
-
|
25
|
-
@pytest.mark.django_db
|
26
|
-
@freeze_time("2021-08-23T14:20:00")
|
27
|
-
def test_nbf_validated():
|
28
|
-
JWTSecret.objects.create(identifier="client", secret="secret")
|
29
|
-
payload = {
|
30
|
-
"client_id": "client",
|
31
|
-
"nbf": int(datetime.now().timestamp())
|
32
|
-
+ 1, # 1 second "later" than current time
|
33
|
-
}
|
34
|
-
token = jwt.encode(payload, "secret", algorithm="HS256")
|
35
|
-
|
36
|
-
auth = JWTAuth(token)
|
37
|
-
|
38
|
-
with pytest.raises(ImmatureSignatureError):
|
39
|
-
auth.payload
|
40
|
-
|
41
|
-
|
42
|
-
@pytest.mark.django_db
|
43
|
-
@freeze_time("2021-08-23T14:20:00")
|
44
|
-
def test_nbf_validated_with_leeway(settings):
|
45
|
-
settings.JWT_LEEWAY = 3
|
46
|
-
JWTSecret.objects.create(identifier="client", secret="secret")
|
47
|
-
payload = {
|
48
|
-
"client_id": "client",
|
49
|
-
"nbf": int(datetime.now().timestamp())
|
50
|
-
+ 1, # 1 second "later" than current time
|
51
|
-
}
|
52
|
-
token = jwt.encode(payload, "secret", algorithm="HS256")
|
53
|
-
|
54
|
-
auth = JWTAuth(token)
|
55
|
-
|
56
|
-
assert auth.payload == payload
|
@@ -1 +0,0 @@
|
|
1
|
-
__version__ = "2.6.5"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_autorisatie_validation.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{commonground_api_common-2.6.5 → commonground_api_common-2.6.7}/tests/test_check_query_params.py
RENAMED
File without changes
|
File without changes
|
File without changes
|