commonground-api-common 2.3.0__py3-none-any.whl → 2.5.0__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-2.3.0.dist-info → commonground_api_common-2.5.0.dist-info}/METADATA +2 -2
- {commonground_api_common-2.3.0.dist-info → commonground_api_common-2.5.0.dist-info}/RECORD +11 -11
- vng_api_common/__init__.py +1 -1
- vng_api_common/apps.py +2 -1
- vng_api_common/contrib/setup_configuration/models.py +10 -2
- vng_api_common/serializers.py +1 -1
- vng_api_common/validators.py +85 -33
- vng_api_common/views.py +2 -2
- {commonground_api_common-2.3.0.data → commonground_api_common-2.5.0.data}/scripts/generate_schema +0 -0
- {commonground_api_common-2.3.0.dist-info → commonground_api_common-2.5.0.dist-info}/WHEEL +0 -0
- {commonground_api_common-2.3.0.dist-info → commonground_api_common-2.5.0.dist-info}/top_level.txt +0 -0
{commonground_api_common-2.3.0.dist-info → commonground_api_common-2.5.0.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: commonground-api-common
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.5.0
|
4
4
|
Summary: Commonground API tooling
|
5
5
|
Home-page: https://github.com/maykinmedia/commonground-api-common
|
6
6
|
Author: Maykin Media, VNG-Realisatie
|
@@ -61,7 +61,7 @@ Requires-Dist: drf-extra-fields; extra == "tests"
|
|
61
61
|
Provides-Extra: testutils
|
62
62
|
Requires-Dist: zgw-consumers-oas; extra == "testutils"
|
63
63
|
Provides-Extra: setup-configuration
|
64
|
-
Requires-Dist: django-setup-configuration>=0.
|
64
|
+
Requires-Dist: django-setup-configuration>=0.7.0; extra == "setup-configuration"
|
65
65
|
Provides-Extra: pep8
|
66
66
|
Requires-Dist: flake8; extra == "pep8"
|
67
67
|
Provides-Extra: coverage
|
@@ -1,7 +1,7 @@
|
|
1
|
-
commonground_api_common-2.
|
2
|
-
vng_api_common/__init__.py,sha256=
|
1
|
+
commonground_api_common-2.5.0.data/scripts/generate_schema,sha256=OpKgzlFc_uzA3TVW_vHSYXAD_feLaCdTEnkWjIcxVzA,280
|
2
|
+
vng_api_common/__init__.py,sha256=fMbNgIJqxiZEaSBLadLBt4rZpCHqarzb4Okt-aWsp2E,22
|
3
3
|
vng_api_common/admin.py,sha256=iFtUPGf-ha0I-bXgq8QIFrP23Kzk_H3FlgAjt0U-ip0,259
|
4
|
-
vng_api_common/apps.py,sha256=
|
4
|
+
vng_api_common/apps.py,sha256=QQiJXRmjX9Q91oh0P9fvVnHe3NSYd1cEcUUBw0HLBCA,3690
|
5
5
|
vng_api_common/checks.py,sha256=tOyfV7MMLGh4anrd_W30LvJCxiyQ4sFs1mGd9mtrEc0,1175
|
6
6
|
vng_api_common/choices.py,sha256=dboFRoM34GpRUpxB9WexexccopcQSogu1QIyY4B9ACY,541
|
7
7
|
vng_api_common/client.py,sha256=HNLc86RwczAudPBDgH_zQncE19OUaLyhSnacQRxJO0c,1972
|
@@ -28,12 +28,12 @@ vng_api_common/routers.py,sha256=hEnhBulkgMM-7W_lYaykKTgTBj3-avl7DGsR9P7BbTU,189
|
|
28
28
|
vng_api_common/schema.py,sha256=axs2Q8IXwpHNd5WscQg5xOErL6bWhP8WFItTt4xCFO4,16305
|
29
29
|
vng_api_common/scopes.py,sha256=PGs6CkXorAAdWXGFY1bSy-jmsPn122Njen9aFFOpFIQ,2351
|
30
30
|
vng_api_common/search.py,sha256=yehS6boCOk1JXLCqAMU-B62hWtbTBSf_WKIVGPgp0Mg,1045
|
31
|
-
vng_api_common/serializers.py,sha256=
|
31
|
+
vng_api_common/serializers.py,sha256=NdrZJqP7p54lRKoKG4mEDS9MqaMcPESIr4dB1tnLaqI,10163
|
32
32
|
vng_api_common/urls.py,sha256=9IWHYLlEIIHNaZ_Zq02qNQ2HJpETb7o-89r7yBM_tQs,270
|
33
33
|
vng_api_common/utils.py,sha256=zrtpssOA-NcJHhAlxioBiXeY3G2R_uf0l8oWkDD_EiE,8511
|
34
|
-
vng_api_common/validators.py,sha256=
|
34
|
+
vng_api_common/validators.py,sha256=ejaFZvFXFaBlqxjA2_07NSHKHlG5pejrfC_GHjwCj6E,12852
|
35
35
|
vng_api_common/version.py,sha256=yJV9_yTM7Qnzg0zGNkJQkN9Uai3I_ZUkcyseJRPRk5I,129
|
36
|
-
vng_api_common/views.py,sha256=
|
36
|
+
vng_api_common/views.py,sha256=pxpI2dl22I9auTYvRJ-Rx-_NHAKgo1F2QwQJF6WIjrE,7603
|
37
37
|
vng_api_common/viewsets.py,sha256=z5pzvSymFiiuCjP_-uuW-3OJKZY_psPAt8fWeWySU0c,2278
|
38
38
|
vng_api_common/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
39
39
|
vng_api_common/api/permissions.py,sha256=okbwiscxlAtbQWTCRDLL2reOxgj0rRDZeDcrtXAYq00,739
|
@@ -108,7 +108,7 @@ vng_api_common/conf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
108
108
|
vng_api_common/conf/api.py,sha256=Lx3Kk7S7mKxeaUr0dm6jbKrEh4WI2gye4i7QxN2x69E,3150
|
109
109
|
vng_api_common/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
110
110
|
vng_api_common/contrib/setup_configuration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
111
|
-
vng_api_common/contrib/setup_configuration/models.py,sha256=
|
111
|
+
vng_api_common/contrib/setup_configuration/models.py,sha256=oqw0cOrbromC9CS3nWzfpDgOLg_xXyHoAi7jgw0f7Yk,1195
|
112
112
|
vng_api_common/contrib/setup_configuration/steps.py,sha256=3jYRdHFlPq5zR-T-SPYTDp_Aipy0JK1HaJFrSgH4Vd0,1680
|
113
113
|
vng_api_common/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
114
114
|
vng_api_common/db/operations.py,sha256=3vj9zD4EntMSmYsNGN1pRDjAcVM68MESDdoAk9wl0U0,3333
|
@@ -182,7 +182,7 @@ vng_api_common/tests/auth.py,sha256=IKDWTEFv4Bign4F70-ibsFcnJqRxEJaXvqaPQJWa1xY,
|
|
182
182
|
vng_api_common/tests/caching.py,sha256=zfIw5cRRvO9cekHZZKfRqZc8cx5IfJUYNmcH6cuIMg4,624
|
183
183
|
vng_api_common/tests/schema.py,sha256=WDvifDQQiKqIpQijpeQ7rYkFroJmuPuHe7zNhl1Bigk,2293
|
184
184
|
vng_api_common/tests/urls.py,sha256=PFrYzQbBC0TFPMEn3uPhcBG0IQs9JsEPqckicJT1UA4,2159
|
185
|
-
commonground_api_common-2.
|
186
|
-
commonground_api_common-2.
|
187
|
-
commonground_api_common-2.
|
188
|
-
commonground_api_common-2.
|
185
|
+
commonground_api_common-2.5.0.dist-info/METADATA,sha256=h6PrcdoJEkOrGklI9qIKWV6YsNIpPilsXP2fG1m-P0Q,6988
|
186
|
+
commonground_api_common-2.5.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
187
|
+
commonground_api_common-2.5.0.dist-info/top_level.txt,sha256=vPismc83zPzWXTmlNCCwfDlFV9iygJYxNJW5iDjKTgw,15
|
188
|
+
commonground_api_common-2.5.0.dist-info/RECORD,,
|
vng_api_common/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "2.
|
1
|
+
__version__ = "2.5.0"
|
vng_api_common/apps.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import logging
|
2
2
|
|
3
3
|
from django.apps import AppConfig
|
4
|
+
from django.core.exceptions import ImproperlyConfigured
|
4
5
|
from django.db import models
|
5
6
|
from django.forms.fields import CharField
|
6
7
|
from django.utils.translation import gettext_lazy as _
|
@@ -89,7 +90,7 @@ def register_geojson_field_extension() -> None:
|
|
89
90
|
"""
|
90
91
|
try:
|
91
92
|
from rest_framework_gis.fields import GeometryField # noqa
|
92
|
-
except ImportError:
|
93
|
+
except (ImportError, ImproperlyConfigured):
|
93
94
|
logger.debug(
|
94
95
|
"Could not import djangorestframework-gis, skipping "
|
95
96
|
"GeometryFieldExtension registration."
|
@@ -13,10 +13,14 @@ class SingleJWTSecretConfigurationModel(ConfigurationModel):
|
|
13
13
|
"secret",
|
14
14
|
]
|
15
15
|
}
|
16
|
+
extra_kwargs = {
|
17
|
+
"identifier": {"examples": ["application-name"]},
|
18
|
+
"secret": {"examples": ["modify-this"]},
|
19
|
+
}
|
16
20
|
|
17
21
|
|
18
22
|
class JWTSecretsConfigurationModel(ConfigurationModel):
|
19
|
-
items: list[SingleJWTSecretConfigurationModel] = Field(
|
23
|
+
items: list[SingleJWTSecretConfigurationModel] = Field()
|
20
24
|
|
21
25
|
|
22
26
|
class SingleApplicatieConfigurationModel(ConfigurationModel):
|
@@ -26,7 +30,11 @@ class SingleApplicatieConfigurationModel(ConfigurationModel):
|
|
26
30
|
django_model_refs = {
|
27
31
|
Applicatie: ["uuid", "client_ids", "label", "heeft_alle_autorisaties"]
|
28
32
|
}
|
33
|
+
extra_kwargs = {
|
34
|
+
"client_ids": {"examples": [["open-notificaties-prod"]]},
|
35
|
+
"label": {"examples": ["Open Notificaties (productie)"]},
|
36
|
+
}
|
29
37
|
|
30
38
|
|
31
39
|
class ApplicatieConfigurationModel(ConfigurationModel):
|
32
|
-
items: list[SingleApplicatieConfigurationModel]
|
40
|
+
items: list[SingleApplicatieConfigurationModel]
|
vng_api_common/serializers.py
CHANGED
@@ -91,7 +91,7 @@ class ValidatieFoutSerializer(FoutSerializer):
|
|
91
91
|
|
92
92
|
|
93
93
|
def add_choice_values_help_text(
|
94
|
-
choices: Union[models.Choices, List[Tuple[str, str]]]
|
94
|
+
choices: Union[models.Choices, List[Tuple[str, str]]],
|
95
95
|
) -> str:
|
96
96
|
is_dj_choices = inspect.isclass(choices) and issubclass(choices, models.Choices)
|
97
97
|
|
vng_api_common/validators.py
CHANGED
@@ -5,7 +5,6 @@ from typing import Callable
|
|
5
5
|
|
6
6
|
from django.conf import settings
|
7
7
|
from django.core.exceptions import ValidationError
|
8
|
-
from django.core.validators import RegexValidator
|
9
8
|
from django.utils import timezone
|
10
9
|
from django.utils.deconstruct import deconstructible
|
11
10
|
from django.utils.module_loading import import_string
|
@@ -13,7 +12,7 @@ from django.utils.translation import gettext_lazy as _
|
|
13
12
|
|
14
13
|
from rest_framework import serializers, validators
|
15
14
|
|
16
|
-
from .constants import RSIN_LENGTH
|
15
|
+
from .constants import BSN_LENGTH, RSIN_LENGTH
|
17
16
|
from .oas import fetcher, obj_has_shape
|
18
17
|
|
19
18
|
logger = logging.getLogger(__name__)
|
@@ -22,6 +21,90 @@ logger = logging.getLogger(__name__)
|
|
22
21
|
WORD_REGEX = re.compile(r"[\w\-]+$", re.ASCII)
|
23
22
|
|
24
23
|
|
24
|
+
class BaseIdentifierValidator:
|
25
|
+
"""
|
26
|
+
Validator base class that performs common validation logic.
|
27
|
+
Digit check, length, and optional 11-proof check.
|
28
|
+
"""
|
29
|
+
|
30
|
+
error_messages = {
|
31
|
+
"isdigit": _("Voer een numerieke waarde in"),
|
32
|
+
"length": _("Waarde moet %(identifier_length)s tekens lang zijn"),
|
33
|
+
"11proefnumber": _("Ongeldige code"),
|
34
|
+
}
|
35
|
+
|
36
|
+
def __init__(
|
37
|
+
self,
|
38
|
+
value: str,
|
39
|
+
identifier_length: int,
|
40
|
+
validate_11proef: bool = False,
|
41
|
+
):
|
42
|
+
self.value = value
|
43
|
+
self.identifier_length = identifier_length
|
44
|
+
self.validate_11proef = validate_11proef
|
45
|
+
|
46
|
+
def validate_isdigit(self) -> None:
|
47
|
+
"""Validates that the value contains only digits."""
|
48
|
+
if not self.value.isdigit():
|
49
|
+
raise ValidationError(self.error_messages["isdigit"], code="only-digits")
|
50
|
+
|
51
|
+
def validate_length(self) -> None:
|
52
|
+
"""Validates that the length of the value is within the allowed sizes."""
|
53
|
+
if len(self.value) != self.identifier_length:
|
54
|
+
raise ValidationError(
|
55
|
+
self.error_messages["length"]
|
56
|
+
% {"identifier_length": self.identifier_length},
|
57
|
+
code="invalid-length",
|
58
|
+
)
|
59
|
+
|
60
|
+
def validate_11proefnumber(self) -> None:
|
61
|
+
"""Validates the value based on the 11-proof check."""
|
62
|
+
total = 0
|
63
|
+
for multiplier, char in enumerate(reversed(self.value), start=1):
|
64
|
+
if multiplier == 1:
|
65
|
+
total += -multiplier * int(char)
|
66
|
+
else:
|
67
|
+
total += multiplier * int(char)
|
68
|
+
|
69
|
+
if total % 11 != 0:
|
70
|
+
raise ValidationError(self.error_messages["11proefnumber"], code="invalid")
|
71
|
+
|
72
|
+
def validate(self) -> None:
|
73
|
+
self.validate_isdigit()
|
74
|
+
self.validate_length()
|
75
|
+
if self.validate_11proef:
|
76
|
+
self.validate_11proefnumber()
|
77
|
+
|
78
|
+
|
79
|
+
def validate_rsin(value: str) -> None:
|
80
|
+
"""
|
81
|
+
Validates that a string value is a valid RSIN number by applying the
|
82
|
+
'11-proef' checking.
|
83
|
+
|
84
|
+
:param value: String object representing a presumably good RSIN number.
|
85
|
+
"""
|
86
|
+
|
87
|
+
validator = BaseIdentifierValidator(
|
88
|
+
value, identifier_length=RSIN_LENGTH, validate_11proef=True
|
89
|
+
)
|
90
|
+
validator.error_messages["11proefnumber"] = _("Onjuist RSIN nummer")
|
91
|
+
validator.validate()
|
92
|
+
|
93
|
+
|
94
|
+
def validate_bsn(value: str) -> None:
|
95
|
+
"""
|
96
|
+
Validates that a string value is a valid BSN number by applying the
|
97
|
+
'11-proef' checking.
|
98
|
+
|
99
|
+
:param value: String object representing a presumably good BSN number.
|
100
|
+
"""
|
101
|
+
validator = BaseIdentifierValidator(
|
102
|
+
value, identifier_length=BSN_LENGTH, validate_11proef=True
|
103
|
+
)
|
104
|
+
validator.error_messages["11proefnumber"] = _("Onjuist BSN nummer")
|
105
|
+
validator.validate()
|
106
|
+
|
107
|
+
|
25
108
|
@deconstructible
|
26
109
|
class AlphanumericExcludingDiacritic:
|
27
110
|
"""
|
@@ -73,37 +156,6 @@ def validate_non_negative_string(value):
|
|
73
156
|
raise ValidationError("De waarde moet een niet-negatief getal zijn.")
|
74
157
|
|
75
158
|
|
76
|
-
validate_digits = RegexValidator(
|
77
|
-
regex="^[0-9]+$", message="Waarde moet numeriek zijn.", code="only-digits"
|
78
|
-
)
|
79
|
-
|
80
|
-
|
81
|
-
def validate_rsin(value):
|
82
|
-
"""
|
83
|
-
Validates that a string value is a valid RSIN number by applying the
|
84
|
-
'11-proef' checking.
|
85
|
-
|
86
|
-
:param value: String object representing a presumably good RSIN number.
|
87
|
-
"""
|
88
|
-
# Initial sanity checks.
|
89
|
-
validate_digits(value)
|
90
|
-
if len(value) != RSIN_LENGTH:
|
91
|
-
raise ValidationError(
|
92
|
-
"RSIN moet %s tekens lang zijn." % RSIN_LENGTH, code="invalid-length"
|
93
|
-
)
|
94
|
-
|
95
|
-
# 11-proef check.
|
96
|
-
total = 0
|
97
|
-
for multiplier, char in enumerate(reversed(value), start=1):
|
98
|
-
if multiplier == 1:
|
99
|
-
total += -multiplier * int(char)
|
100
|
-
else:
|
101
|
-
total += multiplier * int(char)
|
102
|
-
|
103
|
-
if total % 11 != 0:
|
104
|
-
raise ValidationError("Onjuist RSIN nummer.", code="invalid")
|
105
|
-
|
106
|
-
|
107
159
|
class URLValidator:
|
108
160
|
"""
|
109
161
|
Validate that the URL actually resolves to a HTTP 200
|
vng_api_common/views.py
CHANGED
@@ -184,12 +184,12 @@ def _test_nrc_config(check_autorisaties_subscription=True) -> list:
|
|
184
184
|
nrc_client: Optional[Client] = NotificationsConfig.get_client()
|
185
185
|
|
186
186
|
if not nrc_client:
|
187
|
-
return [(
|
187
|
+
return [(_("NRC"), _("Missing"), False)]
|
188
188
|
|
189
189
|
has_nrc_auth = nrc_client.auth is not None if nrc_client else False
|
190
190
|
|
191
191
|
if not nrc_config.notifications_api_service:
|
192
|
-
checks = [(
|
192
|
+
checks = [(_("NRC"), _("Missing"), False)]
|
193
193
|
return checks
|
194
194
|
|
195
195
|
checks = [
|
{commonground_api_common-2.3.0.data → commonground_api_common-2.5.0.data}/scripts/generate_schema
RENAMED
File without changes
|
File without changes
|
{commonground_api_common-2.3.0.dist-info → commonground_api_common-2.5.0.dist-info}/top_level.txt
RENAMED
File without changes
|