commonground-api-common 1.13.4__py3-none-any.whl → 2.0.1__py3-none-any.whl
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-1.13.4.dist-info → commonground_api_common-2.0.1.dist-info}/METADATA +25 -24
- {commonground_api_common-1.13.4.dist-info → commonground_api_common-2.0.1.dist-info}/RECORD +29 -27
- {commonground_api_common-1.13.4.dist-info → commonground_api_common-2.0.1.dist-info}/WHEEL +1 -1
- vng_api_common/__init__.py +1 -1
- vng_api_common/admin.py +1 -20
- vng_api_common/authorizations/admin.py +1 -1
- vng_api_common/authorizations/middleware.py +15 -6
- vng_api_common/authorizations/migrations/0016_remove_authorizationsconfig_api_root_and_more.py +76 -0
- vng_api_common/authorizations/models.py +38 -3
- vng_api_common/authorizations/utils.py +17 -0
- vng_api_common/client.py +56 -27
- vng_api_common/conf/api.py +0 -3
- vng_api_common/management/commands/generate_swagger.py +1 -1
- vng_api_common/migrations/0006_delete_apicredential.py +119 -0
- vng_api_common/mocks.py +4 -1
- vng_api_common/models.py +0 -111
- vng_api_common/notifications/api/views.py +1 -1
- vng_api_common/notifications/handlers.py +8 -3
- vng_api_common/notifications/migrations/0011_remove_subscription_config_and_more.py +23 -0
- vng_api_common/oas.py +0 -3
- vng_api_common/routers.py +3 -3
- vng_api_common/tests/schema.py +12 -0
- vng_api_common/utils.py +0 -22
- vng_api_common/validators.py +0 -38
- vng_api_common/views.py +26 -22
- vng_api_common/notifications/constants.py +0 -3
- vng_api_common/notifications/models.py +0 -97
- {commonground_api_common-1.13.4.data → commonground_api_common-2.0.1.data}/scripts/generate_schema +0 -0
- {commonground_api_common-1.13.4.data → commonground_api_common-2.0.1.data}/scripts/patch_content_types +0 -0
- {commonground_api_common-1.13.4.data → commonground_api_common-2.0.1.data}/scripts/use_external_components +0 -0
- {commonground_api_common-1.13.4.dist-info → commonground_api_common-2.0.1.dist-info}/top_level.txt +0 -0
{commonground_api_common-1.13.4.dist-info → commonground_api_common-2.0.1.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: commonground-api-common
|
3
|
-
Version:
|
3
|
+
Version: 2.0.1
|
4
4
|
Summary: Commonground API tooling
|
5
5
|
Home-page: https://github.com/maykinmedia/commonground-api-common
|
6
6
|
Author: Maykin Media, VNG-Realisatie
|
@@ -9,7 +9,6 @@ License: EUPL 1.2
|
|
9
9
|
Keywords: openapi,swagger,django
|
10
10
|
Classifier: Development Status :: 5 - Production/Stable
|
11
11
|
Classifier: Framework :: Django
|
12
|
-
Classifier: Framework :: Django :: 3.2
|
13
12
|
Classifier: Framework :: Django :: 4.2
|
14
13
|
Classifier: Intended Audience :: Developers
|
15
14
|
Classifier: Operating System :: Unix
|
@@ -20,35 +19,27 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.10
|
21
20
|
Classifier: Programming Language :: Python :: 3.11
|
22
21
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
23
|
-
Requires-Dist: django>=
|
24
|
-
Requires-Dist: django-filter
|
22
|
+
Requires-Dist: django>=4.2.0
|
23
|
+
Requires-Dist: django-filter<=25.1,>=23.1
|
25
24
|
Requires-Dist: django-solo
|
26
|
-
Requires-Dist: djangorestframework>=3.
|
27
|
-
Requires-Dist:
|
25
|
+
Requires-Dist: djangorestframework>=3.15.0
|
26
|
+
Requires-Dist: djangorestframework_camel_case>=1.2.0
|
28
27
|
Requires-Dist: django-rest-framework-condition
|
29
28
|
Requires-Dist: drf-yasg>=1.20.0
|
30
|
-
Requires-Dist: drf-nested-routers>=0.
|
31
|
-
Requires-Dist: gemma-zds-client>=0.14.0
|
29
|
+
Requires-Dist: drf-nested-routers>=0.94.1
|
32
30
|
Requires-Dist: iso-639
|
33
31
|
Requires-Dist: isodate
|
34
|
-
Requires-Dist: notifications-api-common>=0.
|
32
|
+
Requires-Dist: notifications-api-common>=0.3.0
|
33
|
+
Requires-Dist: zgw-consumers>=0.35.1
|
35
34
|
Requires-Dist: oyaml
|
36
|
-
Requires-Dist: PyJWT>=2.0.
|
35
|
+
Requires-Dist: PyJWT>=2.0.1
|
37
36
|
Requires-Dist: requests
|
37
|
+
Requires-Dist: requests-mock
|
38
38
|
Requires-Dist: coreapi
|
39
|
-
|
40
|
-
|
41
|
-
Provides-Extra: docs
|
42
|
-
Requires-Dist: psycopg2; extra == "docs"
|
43
|
-
Requires-Dist: sphinx; extra == "docs"
|
44
|
-
Requires-Dist: sphinx-rtd-theme; extra == "docs"
|
45
|
-
Provides-Extra: markdown_docs
|
39
|
+
Requires-Dist: ape-pie
|
40
|
+
Provides-Extra: markdown-docs
|
46
41
|
Requires-Dist: django-markup<=1.3; extra == "markdown-docs"
|
47
42
|
Requires-Dist: markdown; extra == "markdown-docs"
|
48
|
-
Provides-Extra: pep8
|
49
|
-
Requires-Dist: flake8; extra == "pep8"
|
50
|
-
Provides-Extra: release
|
51
|
-
Requires-Dist: bump2version; extra == "release"
|
52
43
|
Provides-Extra: tests
|
53
44
|
Requires-Dist: psycopg2; extra == "tests"
|
54
45
|
Requires-Dist: pytest; extra == "tests"
|
@@ -59,6 +50,19 @@ Requires-Dist: isort; extra == "tests"
|
|
59
50
|
Requires-Dist: black; extra == "tests"
|
60
51
|
Requires-Dist: requests-mock; extra == "tests"
|
61
52
|
Requires-Dist: freezegun; extra == "tests"
|
53
|
+
Requires-Dist: zgw-consumers-oas; extra == "tests"
|
54
|
+
Provides-Extra: testutils
|
55
|
+
Requires-Dist: zgw-consumers-oas; extra == "testutils"
|
56
|
+
Provides-Extra: pep8
|
57
|
+
Requires-Dist: flake8; extra == "pep8"
|
58
|
+
Provides-Extra: coverage
|
59
|
+
Requires-Dist: pytest-cov; extra == "coverage"
|
60
|
+
Provides-Extra: docs
|
61
|
+
Requires-Dist: psycopg2; extra == "docs"
|
62
|
+
Requires-Dist: sphinx; extra == "docs"
|
63
|
+
Requires-Dist: sphinx-rtd-theme; extra == "docs"
|
64
|
+
Provides-Extra: release
|
65
|
+
Requires-Dist: bump2version; extra == "release"
|
62
66
|
|
63
67
|
===================================================
|
64
68
|
Commonground-API-common - Tooling voor RESTful APIs
|
@@ -97,9 +101,6 @@ Features
|
|
97
101
|
* ``UniekeIdentificatieValidator`` (in combinatie met organisatie)
|
98
102
|
* ``InformatieObjectUniqueValidator`` om te valideren dat M2M entries
|
99
103
|
slechts eenmalig voorkomen
|
100
|
-
* ``ObjectInformatieObjectValidator`` om te valideren dat de synchronisatie
|
101
|
-
van een object-informatieobject relatie pas kan nadat deze relatie in het
|
102
|
-
DRC gemaakt is
|
103
104
|
* ``IsImmutableValidator`` - valideer dat bepaalde velden niet gewijzigd
|
104
105
|
worden bij een (partial) update, maar wel mogen gezet worden bij een create
|
105
106
|
* ``ResourceValidator`` - valideer dat een URL een bepaalde resource ontsluit
|
@@ -1,12 +1,12 @@
|
|
1
|
-
commonground_api_common-
|
2
|
-
commonground_api_common-
|
3
|
-
commonground_api_common-
|
4
|
-
vng_api_common/__init__.py,sha256=
|
5
|
-
vng_api_common/admin.py,sha256=
|
1
|
+
commonground_api_common-2.0.1.data/scripts/generate_schema,sha256=UKhznmbHX1zUjPx8G3XtxUPQiqnyd3TOIXs27Tnjl7U,952
|
2
|
+
commonground_api_common-2.0.1.data/scripts/patch_content_types,sha256=dpGpYrZOZe8O5CHWd0F0QnP6Wk_7lK6DyuVZpBPr4mY,319
|
3
|
+
commonground_api_common-2.0.1.data/scripts/use_external_components,sha256=xvvbngO2aDUagVXv4xRUqPaVtH_eOaVMWLQ8lyAPhEA,369
|
4
|
+
vng_api_common/__init__.py,sha256=wAxkK8w13vqoF47A8iqWdSlIgRRXmZiQ0R4wePZfzhs,22
|
5
|
+
vng_api_common/admin.py,sha256=iFtUPGf-ha0I-bXgq8QIFrP23Kzk_H3FlgAjt0U-ip0,259
|
6
6
|
vng_api_common/apps.py,sha256=wOQuxUImMpH39R0JrDdCZp5ADaUM8jU8vFPFW9froSs,3458
|
7
7
|
vng_api_common/checks.py,sha256=tOyfV7MMLGh4anrd_W30LvJCxiyQ4sFs1mGd9mtrEc0,1175
|
8
8
|
vng_api_common/choices.py,sha256=dboFRoM34GpRUpxB9WexexccopcQSogu1QIyY4B9ACY,541
|
9
|
-
vng_api_common/client.py,sha256=
|
9
|
+
vng_api_common/client.py,sha256=EZWygrJum6pLeKS77mzynfV9kq0gPTjXXSHEpeyEZHg,1888
|
10
10
|
vng_api_common/compat.py,sha256=n4jDFSPzXnh-D_VXjftKMCJYj_q_t6eJrUTWLayl8jQ,768
|
11
11
|
vng_api_common/constants.py,sha256=yYtnYId9alRuhGBoqaO8lkXYi_ATi2FW-wEDGRpiRuQ,10948
|
12
12
|
vng_api_common/decorators.py,sha256=_p-mAyi5Na_-ll00ErcQ3mRoZNCsJzYDAliXn50Bmes,278
|
@@ -20,22 +20,22 @@ vng_api_common/filtersets.py,sha256=Ioarp5t_cz6Hf3iIcP2Rc0D7tGYhcMQPVdIJJ2dvtv8,
|
|
20
20
|
vng_api_common/generators.py,sha256=tD7ZyyFgCQ3KiktpBFtn5YiVdl3jioGxzyvkEZFYdQQ,4911
|
21
21
|
vng_api_common/geo.py,sha256=AZbrw0rwGYOmaSUk8JJSkx-4_tVrfT_cgggh9omRwhU,1862
|
22
22
|
vng_api_common/middleware.py,sha256=2DRw0hPpvUMqwoH1Ze8S7tDB16lmj4Bnd6vN5ijkGM8,875
|
23
|
-
vng_api_common/mocks.py,sha256=
|
24
|
-
vng_api_common/models.py,sha256=
|
25
|
-
vng_api_common/oas.py,sha256=
|
23
|
+
vng_api_common/mocks.py,sha256=0sELLs-uy2ndu29m5P6FN_p1ehNhYv7IoRayYPs379Y,6200
|
24
|
+
vng_api_common/models.py,sha256=3WgpCWQpkCOrMCtqp7EbnP681II43Sg_cch8ZOm4EcU,1707
|
25
|
+
vng_api_common/oas.py,sha256=v_M_nsPRk12VF4lFa3Kw2c-wUThfY8PJ6JlEgeUhz9E,2618
|
26
26
|
vng_api_common/pagination.py,sha256=sI6VJ5AHDBhtNRQ8OFrD2heQK-NxaL_6n73ijiqWDLc,255
|
27
27
|
vng_api_common/permissions.py,sha256=ayDxk9Wt8j0yO57FhZ8XaRkPET4lAqd8SSw3m4o3EGs,7562
|
28
28
|
vng_api_common/polymorphism.py,sha256=N-x39pG2unD4N0ZbxFvuhE8ibPaJ0eKeqfvAJW3NnEU,6623
|
29
|
-
vng_api_common/routers.py,sha256=
|
29
|
+
vng_api_common/routers.py,sha256=hEnhBulkgMM-7W_lYaykKTgTBj3-avl7DGsR9P7BbTU,1897
|
30
30
|
vng_api_common/schema.py,sha256=1Bt9dH67AOLpfPNF7Q4IH1cXJeaIevSamZQzJ8DJ7ks,6144
|
31
31
|
vng_api_common/scopes.py,sha256=PGs6CkXorAAdWXGFY1bSy-jmsPn122Njen9aFFOpFIQ,2351
|
32
32
|
vng_api_common/search.py,sha256=yehS6boCOk1JXLCqAMU-B62hWtbTBSf_WKIVGPgp0Mg,1045
|
33
33
|
vng_api_common/serializers.py,sha256=7_7IotlRfVb0woe6Wy79l_el3sPzrSY8-bfiYLbEUqs,10162
|
34
34
|
vng_api_common/urls.py,sha256=9IWHYLlEIIHNaZ_Zq02qNQ2HJpETb7o-89r7yBM_tQs,270
|
35
|
-
vng_api_common/utils.py,sha256=
|
36
|
-
vng_api_common/validators.py,sha256=
|
35
|
+
vng_api_common/utils.py,sha256=zrtpssOA-NcJHhAlxioBiXeY3G2R_uf0l8oWkDD_EiE,8511
|
36
|
+
vng_api_common/validators.py,sha256=Y1OQrmnH3U01hnCizWc_xjpSSGUWKlwiFxeHHGCThpI,11012
|
37
37
|
vng_api_common/version.py,sha256=yJV9_yTM7Qnzg0zGNkJQkN9Uai3I_ZUkcyseJRPRk5I,129
|
38
|
-
vng_api_common/views.py,sha256=
|
38
|
+
vng_api_common/views.py,sha256=seRGa-_2BPtrtHP6C6mmQCnT10q9ECfRHa8lpwyEcmM,7230
|
39
39
|
vng_api_common/viewsets.py,sha256=z5pzvSymFiiuCjP_-uuW-3OJKZY_psPAt8fWeWySU0c,2278
|
40
40
|
vng_api_common/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
41
41
|
vng_api_common/api/permissions.py,sha256=okbwiscxlAtbQWTCRDLL2reOxgj0rRDZeDcrtXAYq00,739
|
@@ -75,10 +75,11 @@ vng_api_common/audittrails/migrations/0018_auto_20221212_0745.py,sha256=pf4NBYI0
|
|
75
75
|
vng_api_common/audittrails/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
76
76
|
vng_api_common/audittrails/migrations/_operations.py,sha256=UOMv0zAK8CIQ73cSu6wwQG_hkW46Isdy7JCnljn8GII,3280
|
77
77
|
vng_api_common/authorizations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
78
|
-
vng_api_common/authorizations/admin.py,sha256=
|
79
|
-
vng_api_common/authorizations/middleware.py,sha256=
|
80
|
-
vng_api_common/authorizations/models.py,sha256=
|
78
|
+
vng_api_common/authorizations/admin.py,sha256=Tk0yYKbb005E0XZaYYWbucMf_K5M8Hhz62wSBDi8rhM,813
|
79
|
+
vng_api_common/authorizations/middleware.py,sha256=KJ3znCXPRMOVqSur62SmBjvC6RcKxtcWq1rzaHdYR98,8416
|
80
|
+
vng_api_common/authorizations/models.py,sha256=0bcZwRc0ntIlPzUM7I8R5yhQRrnXvAZ_l9FpTnpbnxk,5207
|
81
81
|
vng_api_common/authorizations/serializers.py,sha256=3HeKWEqhI3UWwI8SttC4rEID-Epbk7SWsC-bEjolbaw,5151
|
82
|
+
vng_api_common/authorizations/utils.py,sha256=VCXdU4q3CQ1cvuYkg1dPWSbZym1Ufoz5gSmbHYkQcgw,521
|
82
83
|
vng_api_common/authorizations/validators.py,sha256=u7fKm0QgGy8fiAeYmIEB9Gy-yIE9C-tC2ZpnNQBXPso,2816
|
83
84
|
vng_api_common/authorizations/migrations/0001_initial.py,sha256=ooAZtQeDtWgDxXzAP-KnSyyFYLRPM-PMrK5RgOnTPjQ,4360
|
84
85
|
vng_api_common/authorizations/migrations/0002_authorizationsconfig.py,sha256=m4taH6ClHI-YHYGGOKaq_qYXGx9lq1InXOGLQKg9MSw,1364
|
@@ -95,6 +96,7 @@ vng_api_common/authorizations/migrations/0012_auto_20200619_0545.py,sha256=ECvJJ
|
|
95
96
|
vng_api_common/authorizations/migrations/0013_auto_20201207_0846.py,sha256=fyJ0HpQMM0d1UyK9AK5_c7S_as_NejzrOdbMYiIogOA,1788
|
96
97
|
vng_api_common/authorizations/migrations/0014_auto_20201221_0905.py,sha256=pkg7Y9yvUIY-QB9elvCxfR7OZJ3xMBIha_4WSZeDlwY,1659
|
97
98
|
vng_api_common/authorizations/migrations/0015_auto_20220318_1608.py,sha256=jR1MDuqapBZU4bYVx0V3MRauRpDk_DtCVcBSe7gmtUA,1751
|
99
|
+
vng_api_common/authorizations/migrations/0016_remove_authorizationsconfig_api_root_and_more.py,sha256=-UbTWExHaPL0O8585mm4_OFCm8xJXAmfwmU7V0ysSgg,2407
|
98
100
|
vng_api_common/authorizations/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
99
101
|
vng_api_common/caching/__init__.py,sha256=v_FC6HaHESwr_J94TWzaQBKtIjDLnsQADvqHylEW7g8,687
|
100
102
|
vng_api_common/caching/decorators.py,sha256=lU5dnBjD9aHjoYaV32FlYxY7VFZPdMZe26fVDa_h3Q4,1804
|
@@ -104,7 +106,7 @@ vng_api_common/caching/models.py,sha256=RroS9HFiKNXDV59Odh0x8BO8Az8E81v4gwuprF1A
|
|
104
106
|
vng_api_common/caching/registry.py,sha256=mY1r99x7m0DQ1BN9lZF2zMjFj_oDNq7urxDkOH7-8Yg,6205
|
105
107
|
vng_api_common/caching/signals.py,sha256=78ej5cVan-JpNHKzZNAfs0m2ON_TXKphe8ZKtP-6FVY,4615
|
106
108
|
vng_api_common/conf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
107
|
-
vng_api_common/conf/api.py,sha256=
|
109
|
+
vng_api_common/conf/api.py,sha256=bRc488POvBdKeaKVit7s1_LFP-BRLpETmTzcQ6JD614,4372
|
108
110
|
vng_api_common/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
109
111
|
vng_api_common/db/operations.py,sha256=3vj9zD4EntMSmYsNGN1pRDjAcVM68MESDdoAk9wl0U0,3333
|
110
112
|
vng_api_common/inspectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -122,7 +124,7 @@ vng_api_common/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
122
124
|
vng_api_common/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
123
125
|
vng_api_common/management/commands/generate_autorisaties.py,sha256=kMaZQo6e6vCXA9y0e6P2PlxObyjHMyNynRcM4WtzVZI,1130
|
124
126
|
vng_api_common/management/commands/generate_notificaties.py,sha256=0p7CkLkQo-BeV2IljGv0rcRNw2aWY_HwlvybjggZ_gs,1090
|
125
|
-
vng_api_common/management/commands/generate_swagger.py,sha256=
|
127
|
+
vng_api_common/management/commands/generate_swagger.py,sha256=DyRRSDMFEZeXSJp_PWiMc6vYFK3GPEO4WIRWZV-tlm0,6120
|
126
128
|
vng_api_common/management/commands/patch_error_contenttypes.py,sha256=xyFIQ4JRutLZCTcLrWqon0FDeAJCw1bkVg4jM8-EM24,2025
|
127
129
|
vng_api_common/management/commands/use_external_components.py,sha256=FLkhZ5jAIZoAXQWwxqu4yT94LiBJ4GRr6g4ZRp7b_Eg,2936
|
128
130
|
vng_api_common/migrations/0001_initial.py,sha256=frE83rux6uVHK4v-1fsb_1C00TBQQ6koFBA3DoVPHmk,895
|
@@ -130,15 +132,14 @@ vng_api_common/migrations/0002_apicredential.py,sha256=AYgkLMizI0g-Ogth8j_FVJHTD
|
|
130
132
|
vng_api_common/migrations/0003_auto_20190417_1145.py,sha256=0ABqDggAdjmZxhSsLrMb2ZBwTcR1BOWo1Tn8StfiG0A,1001
|
131
133
|
vng_api_common/migrations/0004_auto_20190517_0903.py,sha256=-Qcei-AJx4SXbEYMojmYInhV74uKtDncGP1PLs6hn0M,707
|
132
134
|
vng_api_common/migrations/0005_auto_20190614_1346.py,sha256=5n8SVpbEJzLrSx-7d446Vy1--SaDfO05hAltrSRQx6o,2949
|
135
|
+
vng_api_common/migrations/0006_delete_apicredential.py,sha256=VMVwH4vj9Zq-oF_Z1Do9wobgePtkujwd8bO8M57ACt0,3621
|
133
136
|
vng_api_common/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
134
137
|
vng_api_common/notifications/__init__.py,sha256=UvHr_M8s-dZjCQOp60rLDqP_T3D0CgRIqc8ry5bIM8c,229
|
135
138
|
vng_api_common/notifications/apps.py,sha256=7grk1hxQn5usAWV-sWATmNJ4TwSvT3izXVvV-L-zb_s,208
|
136
|
-
vng_api_common/notifications/
|
137
|
-
vng_api_common/notifications/handlers.py,sha256=-r52nIKbHdFUxE7hob9PiFRe0D3cizhkxbW8qhpK-Ks,2005
|
138
|
-
vng_api_common/notifications/models.py,sha256=Ez3JYeM7BNSiFYtxAtVxWUWDc8t7jOFQlRTjrtE6SlI,2942
|
139
|
+
vng_api_common/notifications/handlers.py,sha256=xjuE_qn5h4gbRNGMsTaCTrHIjXTBcF8na6oMURGAuUU,2089
|
139
140
|
vng_api_common/notifications/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
140
141
|
vng_api_common/notifications/api/urls.py,sha256=c1T_6tuRpgN0V80Xg_ehZzGGlF1FNMmHdBEPAjR736I,164
|
141
|
-
vng_api_common/notifications/api/views.py,sha256=
|
142
|
+
vng_api_common/notifications/api/views.py,sha256=EvppqaANutuOIrkNepavmzFTX6fxo32c6l5c6DKHe8k,2326
|
142
143
|
vng_api_common/notifications/migrations/0001_initial.py,sha256=zEIVIB--6FStaTl3r9GCXxHL1cSCWRO3T90rEpJr3hY,3049
|
143
144
|
vng_api_common/notifications/migrations/0002_subscription__subscription.py,sha256=eqaj6-FAl7vuCswdvin9Lf8nzjP8U6WqVQO4opNKKCc,550
|
144
145
|
vng_api_common/notifications/migrations/0003_auto_20190319_1048.py,sha256=C-ccYUwQPNCjTctpDDFhnQbm_OcpAlTjYQbEuiEi-ys,987
|
@@ -149,6 +150,7 @@ vng_api_common/notifications/migrations/0007_auto_20190429_1442.py,sha256=S9Q_WC
|
|
149
150
|
vng_api_common/notifications/migrations/0008_auto_20190502_0415.py,sha256=Wwh3BsSg0r1I7HZZmrcCHEQMLmaeWEjbqYKapVafb2s,523
|
150
151
|
vng_api_common/notifications/migrations/0009_auto_20190729_0427.py,sha256=Bfw-Axr9lNiXL8Ghns3RK33Dmjvpd_E5MWC740WJlb8,529
|
151
152
|
vng_api_common/notifications/migrations/0010_auto_20220704_1419.py,sha256=Y57o91fbzWZyQO4tgg9Tn4r99hRErRlcrzpLii9Tm3I,1593
|
153
|
+
vng_api_common/notifications/migrations/0011_remove_subscription_config_and_more.py,sha256=3FA3rlpRDp8FB8Azl22pv7C4i1oUAQkRHHK9PRpNeJU,499
|
152
154
|
vng_api_common/notifications/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
153
155
|
vng_api_common/static/vng_api_common/css/screen.css,sha256=1Zt-yVFbm8qR9LakcYTF5x8p_91r8dMA-VRjIadYeP0,4674
|
154
156
|
vng_api_common/static/vng_api_common/css/admin/admin_overrides.css,sha256=81xuIyYfiTgq8O9h5NsSf-v8Sx885ICSEx1f-5fWy4U,1748
|
@@ -187,9 +189,9 @@ vng_api_common/templatetags/vng_api_common.py,sha256=j4Fu4rNErLcXStBbuZ9Zd_xD_ft
|
|
187
189
|
vng_api_common/tests/__init__.py,sha256=zBI2etwu2lEkKkIN1_cPuugJgPcoohQuJbdiUGtoceU,426
|
188
190
|
vng_api_common/tests/auth.py,sha256=IKDWTEFv4Bign4F70-ibsFcnJqRxEJaXvqaPQJWa1xY,4544
|
189
191
|
vng_api_common/tests/caching.py,sha256=zfIw5cRRvO9cekHZZKfRqZc8cx5IfJUYNmcH6cuIMg4,624
|
190
|
-
vng_api_common/tests/schema.py,sha256=
|
192
|
+
vng_api_common/tests/schema.py,sha256=irt_kIp1uJsnYIJlrpk0-qM9W6i44WyX3GSiJvGUfdU,2288
|
191
193
|
vng_api_common/tests/urls.py,sha256=PFrYzQbBC0TFPMEn3uPhcBG0IQs9JsEPqckicJT1UA4,2159
|
192
|
-
commonground_api_common-
|
193
|
-
commonground_api_common-
|
194
|
-
commonground_api_common-
|
195
|
-
commonground_api_common-
|
194
|
+
commonground_api_common-2.0.1.dist-info/METADATA,sha256=-xJGeWAsWqA4c1ZWjSmfVaEJl7AcHAyvGuGwLbgyAws,6497
|
195
|
+
commonground_api_common-2.0.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
196
|
+
commonground_api_common-2.0.1.dist-info/top_level.txt,sha256=vPismc83zPzWXTmlNCCwfDlFV9iygJYxNJW5iDjKTgw,15
|
197
|
+
commonground_api_common-2.0.1.dist-info/RECORD,,
|
vng_api_common/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "
|
1
|
+
__version__ = "2.0.1"
|
vng_api_common/admin.py
CHANGED
@@ -1,29 +1,10 @@
|
|
1
1
|
from django.contrib import admin
|
2
2
|
from django.utils.translation import gettext_lazy as _
|
3
3
|
|
4
|
-
from .models import
|
4
|
+
from .models import JWTSecret
|
5
5
|
|
6
6
|
|
7
7
|
@admin.register(JWTSecret)
|
8
8
|
class JWTSecretAdmin(admin.ModelAdmin):
|
9
9
|
list_display = ("identifier",)
|
10
10
|
search_fields = ("identifier",)
|
11
|
-
|
12
|
-
|
13
|
-
@admin.register(APICredential)
|
14
|
-
class APICredentialAdmin(admin.ModelAdmin):
|
15
|
-
list_display = ("label", "api_root", "client_id", "user_id")
|
16
|
-
search_fields = ("label", "api_root")
|
17
|
-
fieldsets = (
|
18
|
-
(_("external API"), {"fields": ["api_root", "label"]}),
|
19
|
-
(
|
20
|
-
_("credentials"),
|
21
|
-
{
|
22
|
-
"description": _(
|
23
|
-
"Credentials that indicate how this API or application identifies itself at the external "
|
24
|
-
"API."
|
25
|
-
),
|
26
|
-
"fields": ["client_id", "secret", "user_id", "user_representation"],
|
27
|
-
},
|
28
|
-
),
|
29
|
-
)
|
@@ -7,7 +7,7 @@ from .models import Applicatie, AuthorizationsConfig, Autorisatie
|
|
7
7
|
|
8
8
|
@admin.register(AuthorizationsConfig)
|
9
9
|
class AuthorizationsConfigAdmin(SingletonModelAdmin):
|
10
|
-
list_display = ("
|
10
|
+
list_display = ("authorizations_api_service", "component")
|
11
11
|
|
12
12
|
|
13
13
|
@admin.register(Autorisatie)
|
@@ -8,9 +8,10 @@ from django.utils.translation import gettext as _
|
|
8
8
|
|
9
9
|
import jwt
|
10
10
|
from djangorestframework_camel_case.util import underscoreize
|
11
|
+
from requests import RequestException
|
11
12
|
from rest_framework.exceptions import PermissionDenied
|
12
|
-
from zds_client.client import ClientError
|
13
13
|
|
14
|
+
from vng_api_common.client import ClientError, to_internal_data
|
14
15
|
from vng_api_common.constants import VertrouwelijkheidsAanduiding
|
15
16
|
|
16
17
|
from ..models import JWTSecret
|
@@ -51,10 +52,18 @@ class JWTAuth:
|
|
51
52
|
|
52
53
|
def _request_auth(self) -> list:
|
53
54
|
client = AuthorizationsConfig.get_client()
|
55
|
+
|
56
|
+
if not client:
|
57
|
+
logger.warning("Authorization component can't be accessed")
|
58
|
+
return []
|
59
|
+
|
54
60
|
try:
|
55
|
-
response = client.
|
56
|
-
|
57
|
-
)
|
61
|
+
response = client.get("applicaties", params={"clientIds": self.client_id})
|
62
|
+
|
63
|
+
data = to_internal_data(response)
|
64
|
+
except RequestException:
|
65
|
+
logger.warning("Authorization component can't be accessed")
|
66
|
+
return []
|
58
67
|
except ClientError as exc:
|
59
68
|
response = exc.args[0]
|
60
69
|
# friendly debug - hint at where the problem is located
|
@@ -64,10 +73,10 @@ class JWTAuth:
|
|
64
73
|
"authorizations could not be retrieved"
|
65
74
|
)
|
66
75
|
raise PermissionDenied(detail=detail, code="not_authenticated_for_ac")
|
67
|
-
logger.
|
76
|
+
logger.warning("Authorization component can't be accessed")
|
68
77
|
return []
|
69
78
|
|
70
|
-
return underscoreize(
|
79
|
+
return underscoreize(data["results"])
|
71
80
|
|
72
81
|
def _get_auth(self):
|
73
82
|
return Applicatie.objects.filter(client_ids__contains=[self.client_id])
|
vng_api_common/authorizations/migrations/0016_remove_authorizationsconfig_api_root_and_more.py
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# Generated by Django 5.1.2 on 2024-10-25 14:07
|
2
|
+
|
3
|
+
import logging
|
4
|
+
|
5
|
+
import django.db.models.deletion
|
6
|
+
from django.db import migrations, models
|
7
|
+
from django.utils.text import slugify
|
8
|
+
|
9
|
+
from zgw_consumers.constants import APITypes, AuthTypes
|
10
|
+
|
11
|
+
logger = logging.getLogger(__name__)
|
12
|
+
|
13
|
+
|
14
|
+
def migrate_authorization_config_to_service(apps, _) -> None:
|
15
|
+
AuthorizationsConfig = apps.get_model("authorizations", "AuthorizationsConfig")
|
16
|
+
Service = apps.get_model("zgw_consumers", "Service")
|
17
|
+
|
18
|
+
service_label = "Authorization API service"
|
19
|
+
|
20
|
+
config, _ = AuthorizationsConfig.objects.get_or_create()
|
21
|
+
service, created = Service.objects.get_or_create(
|
22
|
+
api_root=config.api_root,
|
23
|
+
defaults=dict(
|
24
|
+
label="Authorization API service",
|
25
|
+
slug=slugify(service_label),
|
26
|
+
api_type=APITypes.ac,
|
27
|
+
auth_type=AuthTypes.zgw,
|
28
|
+
),
|
29
|
+
)
|
30
|
+
config.authorizations_api_service = service
|
31
|
+
config.save()
|
32
|
+
|
33
|
+
if created:
|
34
|
+
logger.info(f"Created new Service for {config.api_root}")
|
35
|
+
else:
|
36
|
+
logger.info(f"Existing service found for {config.api_root}")
|
37
|
+
|
38
|
+
|
39
|
+
def migrate_authorization_config_to_config(apps, _) -> None:
|
40
|
+
AuthorizationsConfig = apps.get_model("authorizations", "AuthorizationsConfig")
|
41
|
+
|
42
|
+
config, _ = AuthorizationsConfig.objects.get_or_create()
|
43
|
+
if config.authorizations_api_service:
|
44
|
+
config.api_root = config.authorizations_api_service.api_root
|
45
|
+
config.save()
|
46
|
+
|
47
|
+
|
48
|
+
class Migration(migrations.Migration):
|
49
|
+
|
50
|
+
dependencies = [
|
51
|
+
("authorizations", "0015_auto_20220318_1608"),
|
52
|
+
("zgw_consumers", "0022_set_default_service_slug"),
|
53
|
+
]
|
54
|
+
|
55
|
+
operations = [
|
56
|
+
migrations.AddField(
|
57
|
+
model_name="authorizationsconfig",
|
58
|
+
name="authorizations_api_service",
|
59
|
+
field=models.ForeignKey(
|
60
|
+
blank=True,
|
61
|
+
limit_choices_to={"api_type": "ac", "auth_type": "zgw"},
|
62
|
+
null=True,
|
63
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
64
|
+
to="zgw_consumers.service",
|
65
|
+
verbose_name="autorisations api service",
|
66
|
+
),
|
67
|
+
),
|
68
|
+
migrations.RunPython(
|
69
|
+
migrate_authorization_config_to_service,
|
70
|
+
reverse_code=migrate_authorization_config_to_config,
|
71
|
+
),
|
72
|
+
migrations.RemoveField(
|
73
|
+
model_name="authorizationsconfig",
|
74
|
+
name="api_root",
|
75
|
+
),
|
76
|
+
]
|
@@ -1,17 +1,28 @@
|
|
1
1
|
import uuid
|
2
|
+
from typing import Optional
|
2
3
|
|
3
4
|
from django.contrib.postgres.fields import ArrayField
|
4
5
|
from django.db import models
|
5
6
|
from django.utils.translation import gettext_lazy as _
|
6
7
|
|
8
|
+
from solo.models import SingletonModel
|
9
|
+
from zgw_consumers.constants import APITypes, AuthTypes
|
10
|
+
|
11
|
+
from vng_api_common.client import Client, get_client
|
12
|
+
|
7
13
|
from ..constants import ComponentTypes, VertrouwelijkheidsAanduiding
|
8
14
|
from ..decorators import field_default
|
9
15
|
from ..fields import VertrouwelijkheidsAanduidingField
|
10
|
-
from ..models import APIMixin
|
16
|
+
from ..models import APIMixin
|
17
|
+
|
11
18
|
|
19
|
+
class AuthorizationsConfigManager(models.Manager):
|
20
|
+
def get_queryset(self):
|
21
|
+
qs = super().get_queryset()
|
22
|
+
return qs.select_related("authorizations_api_service")
|
12
23
|
|
13
|
-
|
14
|
-
class AuthorizationsConfig(
|
24
|
+
|
25
|
+
class AuthorizationsConfig(SingletonModel):
|
15
26
|
component = models.CharField(
|
16
27
|
_("component"),
|
17
28
|
max_length=50,
|
@@ -19,9 +30,33 @@ class AuthorizationsConfig(ClientConfig):
|
|
19
30
|
default=ComponentTypes.zrc,
|
20
31
|
)
|
21
32
|
|
33
|
+
authorizations_api_service = models.ForeignKey(
|
34
|
+
"zgw_consumers.Service",
|
35
|
+
limit_choices_to=dict(
|
36
|
+
api_type=APITypes.ac,
|
37
|
+
auth_type=AuthTypes.zgw,
|
38
|
+
),
|
39
|
+
verbose_name=_("autorisations api service"),
|
40
|
+
on_delete=models.SET_NULL,
|
41
|
+
blank=True,
|
42
|
+
null=True,
|
43
|
+
)
|
44
|
+
|
45
|
+
objects = AuthorizationsConfigManager()
|
46
|
+
|
22
47
|
class Meta:
|
23
48
|
verbose_name = _("Autorisatiecomponentconfiguratie")
|
24
49
|
|
50
|
+
@classmethod
|
51
|
+
def get_client(cls) -> Optional[Client]:
|
52
|
+
"""
|
53
|
+
Construct a client, prepared with the required auth.
|
54
|
+
"""
|
55
|
+
config = cls.get_solo()
|
56
|
+
if config.authorizations_api_service:
|
57
|
+
return get_client(config.authorizations_api_service.api_root)
|
58
|
+
return None
|
59
|
+
|
25
60
|
|
26
61
|
class ApplicatieManager(models.Manager):
|
27
62
|
def get_by_natural_key(self, uuid):
|
@@ -0,0 +1,17 @@
|
|
1
|
+
def generate_jwt(client_id, secret, user_id, user_representation):
|
2
|
+
from zgw_consumers.client import ZGWAuth
|
3
|
+
|
4
|
+
class FakeService:
|
5
|
+
def __init__(self, **kwargs):
|
6
|
+
for key, value in kwargs.items():
|
7
|
+
setattr(self, key, value)
|
8
|
+
|
9
|
+
auth = ZGWAuth(
|
10
|
+
service=FakeService( # type: ignore
|
11
|
+
client_id=client_id,
|
12
|
+
secret=secret,
|
13
|
+
user_id=user_id,
|
14
|
+
user_representation=user_representation,
|
15
|
+
)
|
16
|
+
)
|
17
|
+
return f"Bearer {auth._token}"
|
vng_api_common/client.py
CHANGED
@@ -1,44 +1,73 @@
|
|
1
1
|
"""
|
2
|
-
Interface to get a
|
2
|
+
Interface to get a client object for a given URL.
|
3
3
|
"""
|
4
4
|
|
5
|
-
|
5
|
+
import logging
|
6
|
+
from typing import Any, Optional
|
6
7
|
|
7
|
-
from django.apps import apps
|
8
8
|
from django.conf import settings
|
9
9
|
from django.utils.module_loading import import_string
|
10
10
|
|
11
|
-
from
|
11
|
+
from ape_pie import APIClient
|
12
|
+
from requests import JSONDecodeError, RequestException, Response
|
12
13
|
|
14
|
+
logger = logging.getLogger(__name__)
|
13
15
|
|
14
|
-
def get_client(url: str, url_is_api_root=False) -> Optional[Client]:
|
15
|
-
"""
|
16
|
-
Get a client instance for the given URL.
|
17
16
|
|
18
|
-
|
19
|
-
|
17
|
+
class ClientError(RuntimeError):
|
18
|
+
pass
|
20
19
|
|
21
|
-
If no suitable client is found, ``None`` is returned.
|
22
|
-
"""
|
23
|
-
custom_client_fetcher = getattr(settings, "CUSTOM_CLIENT_FETCHER", None)
|
24
|
-
if custom_client_fetcher:
|
25
|
-
client_getter = import_string(custom_client_fetcher)
|
26
|
-
return client_getter(url)
|
27
20
|
|
28
|
-
|
29
|
-
|
21
|
+
# TODO: use more approriate method name
|
22
|
+
def to_internal_data(response: Response) -> dict | list | None:
|
23
|
+
try:
|
24
|
+
response_json = response.json()
|
25
|
+
except JSONDecodeError:
|
26
|
+
logger.exception("Unable to parse json from response")
|
27
|
+
response_json = None
|
30
28
|
|
31
|
-
|
32
|
-
|
29
|
+
try:
|
30
|
+
response.raise_for_status()
|
31
|
+
except RequestException as exc:
|
32
|
+
if response.status_code >= 500:
|
33
|
+
raise
|
34
|
+
raise ClientError(response_json if response_json is not None else {}) from exc
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
-
|
36
|
+
assert response_json
|
37
|
+
return response_json
|
38
|
+
|
39
|
+
|
40
|
+
class Client(APIClient):
|
41
|
+
def request(
|
42
|
+
self, method: str | bytes, url: str | bytes, *args, **kwargs
|
43
|
+
) -> Response:
|
44
|
+
|
45
|
+
headers = kwargs.pop("headers", {})
|
46
|
+
headers.setdefault("Accept", "application/json")
|
47
|
+
headers.setdefault("Content-Type", "application/json")
|
48
|
+
|
49
|
+
kwargs["headers"] = headers
|
50
|
+
|
51
|
+
data = kwargs.get("data", {})
|
37
52
|
|
38
|
-
|
53
|
+
if data:
|
54
|
+
kwargs["json"] = data
|
39
55
|
|
40
|
-
|
41
|
-
|
56
|
+
return super().request(method, url, *args, **kwargs)
|
57
|
+
|
58
|
+
|
59
|
+
def get_client(url: str) -> Client | None:
|
60
|
+
"""
|
61
|
+
Get a client instance for the given URL.
|
62
|
+
If no suitable client is found, ``None`` is returned.
|
63
|
+
"""
|
64
|
+
from zgw_consumers.client import build_client
|
65
|
+
from zgw_consumers.models import Service
|
66
|
+
|
67
|
+
service: Optional[Service] = Service.get_service(url)
|
68
|
+
|
69
|
+
if not service:
|
70
|
+
logger.warning(f"No service configured for {url}")
|
71
|
+
return None
|
42
72
|
|
43
|
-
|
44
|
-
return client
|
73
|
+
return build_client(service, client_factory=Client)
|
vng_api_common/conf/api.py
CHANGED
@@ -4,7 +4,6 @@ __all__ = [
|
|
4
4
|
"BASE_SWAGGER_SETTINGS",
|
5
5
|
"COMMON_SPEC",
|
6
6
|
"LINK_FETCHER",
|
7
|
-
"ZDS_CLIENT_CLASS",
|
8
7
|
"GEMMA_URL_TEMPLATE",
|
9
8
|
"GEMMA_URL_COMPONENTTYPE",
|
10
9
|
"GEMMA_URL_INFORMATIEMODEL",
|
@@ -94,8 +93,6 @@ REDOC_SETTINGS = {"EXPAND_RESPONSES": "200,201", "SPEC_URL": "openapi.json"}
|
|
94
93
|
# See: https://github.com/Rebilly/ReDoc#redoc-options-object
|
95
94
|
LINK_FETCHER = "requests.get"
|
96
95
|
|
97
|
-
ZDS_CLIENT_CLASS = "zds_client.Client"
|
98
|
-
|
99
96
|
GEMMA_URL_TEMPLATE = "https://www.gemmaonline.nl/index.php/{informatiemodel}_{versie}/doc/{componenttype}/{component}"
|
100
97
|
GEMMA_URL_COMPONENTTYPE = "objecttype"
|
101
98
|
GEMMA_URL_INFORMATIEMODEL = "Rgbz"
|