nucliadb-utils 5.0.0.post641__py3-none-any.whl → 5.0.0.post642__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.
@@ -0,0 +1,81 @@
1
+ # Copyright (C) 2021 Bosutech XXI S.L.
2
+ #
3
+ # nucliadb is offered under the AGPL v3.0 and as commercial software.
4
+ # For commercial licensing, contact us at info@nuclia.com.
5
+ #
6
+ # AGPL:
7
+ # This program is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Affero General Public License as
9
+ # published by the Free Software Foundation, either version 3 of the
10
+ # License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Affero General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Affero General Public License
18
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ import base64
21
+ import binascii
22
+
23
+ import nacl.exceptions
24
+ import nacl.secret
25
+ import nacl.utils
26
+
27
+ from nucliadb_telemetry.metrics import Observer
28
+
29
+
30
+ class DecryptionError(Exception): ...
31
+
32
+
33
+ class DecryptionDataError(DecryptionError): ...
34
+
35
+
36
+ endecryptor_observer = Observer(
37
+ "endecryptor",
38
+ error_mappings={
39
+ "DecryptionError": DecryptionError,
40
+ "DecryptionDataError": DecryptionDataError,
41
+ },
42
+ labels={"operation": ""},
43
+ )
44
+
45
+
46
+ class EndecryptorUtility:
47
+ """
48
+ Utility class for encryption and decryption of sensitive data using the nacl library.
49
+ """
50
+
51
+ def __init__(self, secret_key: bytes):
52
+ try:
53
+ self.box = nacl.secret.SecretBox(secret_key)
54
+ except nacl.exceptions.TypeError as ex:
55
+ raise ValueError("Invalid secret key") from ex
56
+
57
+ @classmethod
58
+ def from_b64_encoded_secret_key(cls, encoded_secret_key: str):
59
+ try:
60
+ secret_key = base64.b64decode(encoded_secret_key)
61
+ except binascii.Error as ex:
62
+ raise ValueError("Invalid base64 encoding") from ex
63
+ return cls(secret_key=secret_key)
64
+
65
+ @endecryptor_observer.wrap({"operation": "encrypt"})
66
+ def encrypt(self, text: str) -> str:
67
+ text_bytes = text.encode()
68
+ encrypted = self.box.encrypt(text_bytes)
69
+ return encrypted.hex()
70
+
71
+ @endecryptor_observer.wrap({"operation": "decrypt"})
72
+ def decrypt(self, encrypted_text: str) -> str:
73
+ try:
74
+ encrypted = nacl.utils.EncryptedMessage.fromhex(encrypted_text)
75
+ except ValueError as ex:
76
+ raise DecryptionDataError("Error decrypting the message") from ex
77
+ try:
78
+ decrypted_bytes = self.box.decrypt(encrypted)
79
+ except nacl.exceptions.CryptoError as ex:
80
+ raise DecryptionError("Error decrypting the message") from ex
81
+ return decrypted_bytes.decode()
@@ -0,0 +1,39 @@
1
+ # Copyright (C) 2021 Bosutech XXI S.L.
2
+ #
3
+ # nucliadb is offered under the AGPL v3.0 and as commercial software.
4
+ # For commercial licensing, contact us at info@nuclia.com.
5
+ #
6
+ # AGPL:
7
+ # This program is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Affero General Public License as
9
+ # published by the Free Software Foundation, either version 3 of the
10
+ # License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Affero General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Affero General Public License
18
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+ from typing import Optional
20
+
21
+ from pydantic import Field
22
+ from pydantic_settings import BaseSettings
23
+
24
+
25
+ class EncryptionSettings(BaseSettings):
26
+ encryption_secret_key: Optional[str] = Field(
27
+ default=None,
28
+ title="Encryption Secret Key",
29
+ description="""Secret key used for encryption and decryption of sensitive data in the database.
30
+ The key must be a 32-byte string, base64 encoded. You can generate a new key with the following unix command:
31
+ head -c 32 /dev/urandom | base64
32
+ """,
33
+ examples=[
34
+ "6TGjSkvX6qkFOo/BJKl5OY1fwJoWnMaSVI7VOJjU07Y=",
35
+ ],
36
+ )
37
+
38
+
39
+ settings = EncryptionSettings()
@@ -34,6 +34,8 @@ from nucliadb_utils.audit.stream import StreamAuditStorage
34
34
  from nucliadb_utils.cache.nats import NatsPubsub
35
35
  from nucliadb_utils.cache.pubsub import PubSubDriver
36
36
  from nucliadb_utils.cache.settings import settings as cache_settings
37
+ from nucliadb_utils.encryption import EndecryptorUtility
38
+ from nucliadb_utils.encryption.settings import settings as encryption_settings
37
39
  from nucliadb_utils.exceptions import ConfigurationError
38
40
  from nucliadb_utils.indexing import IndexingUtility
39
41
  from nucliadb_utils.nats import NatsConnectionManager
@@ -78,6 +80,7 @@ class Utility(str, Enum):
78
80
  LOCAL_STORAGE = "local_storage"
79
81
  NUCLIA_STORAGE = "nuclia_storage"
80
82
  MAINDB_DRIVER = "driver"
83
+ ENDECRYPTOR = "endecryptor"
81
84
 
82
85
 
83
86
  def get_utility(ident: Union[Utility, str]):
@@ -406,3 +409,19 @@ def has_feature(
406
409
  if X_ACCOUNT_TYPE_HEADER in headers:
407
410
  context["account_type"] = headers[X_ACCOUNT_TYPE_HEADER]
408
411
  return get_feature_flags().enabled(name, default=default, context=context)
412
+
413
+
414
+ def get_endecryptor() -> EndecryptorUtility:
415
+ util = get_utility(Utility.ENDECRYPTOR)
416
+ if util is not None:
417
+ return util
418
+ if encryption_settings.encryption_secret_key is None:
419
+ raise ConfigurationError("Encryption secret key not configured")
420
+ try:
421
+ util = EndecryptorUtility.from_b64_encoded_secret_key(encryption_settings.encryption_secret_key)
422
+ except ValueError as ex:
423
+ raise ConfigurationError(
424
+ "Invalid encryption key. Must be a base64 encoded 32-byte string"
425
+ ) from ex
426
+ set_utility(Utility.ENDECRYPTOR, util)
427
+ return util
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: nucliadb_utils
3
- Version: 5.0.0.post641
3
+ Version: 5.0.0.post642
4
4
  Home-page: https://nuclia.com
5
5
  License: BSD
6
6
  Classifier: Development Status :: 4 - Beta
@@ -23,8 +23,8 @@ Requires-Dist: PyNaCl
23
23
  Requires-Dist: pyjwt >=2.4.0
24
24
  Requires-Dist: memorylru >=1.1.2
25
25
  Requires-Dist: mrflagly
26
- Requires-Dist: nucliadb-protos >=5.0.0.post641
27
- Requires-Dist: nucliadb-telemetry >=5.0.0.post641
26
+ Requires-Dist: nucliadb-protos >=5.0.0.post642
27
+ Requires-Dist: nucliadb-telemetry >=5.0.0.post642
28
28
  Provides-Extra: cache
29
29
  Requires-Dist: redis >=4.3.4 ; extra == 'cache'
30
30
  Requires-Dist: orjson >=3.6.7 ; extra == 'cache'
@@ -16,7 +16,7 @@ nucliadb_utils/settings.py,sha256=AaOtQZVRqRcMnUyN1l1MpR10lANaDT2uPrbhmTyn6uk,76
16
16
  nucliadb_utils/signals.py,sha256=JRNv2y9zLtBjOANBf7krGfDGfOc9qcoXZ6N1nKWS2FE,2674
17
17
  nucliadb_utils/store.py,sha256=kQ35HemE0v4_Qg6xVqNIJi8vSFAYQtwI3rDtMsNy62Y,890
18
18
  nucliadb_utils/transaction.py,sha256=mwcI3aIHAvU5KOGqd_Uz_d1XQzXhk_-NWY8NqU1lfb0,7307
19
- nucliadb_utils/utilities.py,sha256=puBRsquZEM3gnXNI8wPwXzG1gN8Gg86B7g-oJFlrXQQ,14188
19
+ nucliadb_utils/utilities.py,sha256=ABcv4PwRYlrFOFOJF-1TU8PVbmW548g7scs-dsEJDp0,14955
20
20
  nucliadb_utils/audit/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
21
21
  nucliadb_utils/audit/audit.py,sha256=dn5ZnCVQUlCcvdjzaORghbrjk9QgVGrtkfIftq30Bp8,2819
22
22
  nucliadb_utils/audit/basic.py,sha256=NViey6mKbCXqRTLDBX2xNTcCg9I-2e4oB2xkekuhDvM,3392
@@ -26,6 +26,8 @@ nucliadb_utils/cache/exceptions.py,sha256=Zu-O_-0-yctOEgoDGI92gPzWfBMRrpiAyESA62
26
26
  nucliadb_utils/cache/nats.py,sha256=-AjCfkFgKVdJUlGR0hT9JDSNkPVFg4S6w9eW-ZIcXPM,7037
27
27
  nucliadb_utils/cache/pubsub.py,sha256=l8i_RwRf7OPzfmPy-gyn66xgYFs5aHidCIjEaU9VOHE,1654
28
28
  nucliadb_utils/cache/settings.py,sha256=WVeHOE6Re5i4k2hUHdFKfkoL4n83v_Z6UPBK6GHYb8g,1059
29
+ nucliadb_utils/encryption/__init__.py,sha256=oav6jFOTGgmIen88sdmy-bCK-uj1tyDt2hr7lB2YKik,2690
30
+ nucliadb_utils/encryption/settings.py,sha256=yF2AW6c_mu0yWbBn1grAERDAqDvKIpXqQnwD0OFmROI,1467
29
31
  nucliadb_utils/fastapi/__init__.py,sha256=itSI7dtTwFP55YMX4iK7JzdMHS5CQVUiB1XzQu4UBh8,833
30
32
  nucliadb_utils/fastapi/openapi.py,sha256=b0pLuri0QuzQd0elDyOVXM42YYmES_cmT-jEfsQ1G6Y,1737
31
33
  nucliadb_utils/fastapi/run.py,sha256=n6vOX64QqF1I5n4UlKnpm_ZJ24rmwfRGi-J9YMGpZzA,3631
@@ -58,8 +60,8 @@ nucliadb_utils/tests/indexing.py,sha256=YW2QhkhO9Q_8A4kKWJaWSvXvyQ_AiAwY1VylcfVQ
58
60
  nucliadb_utils/tests/local.py,sha256=c3gZJJWmvOftruJkIQIwB3q_hh3uxEhqGIAVWim1Bbk,1343
59
61
  nucliadb_utils/tests/nats.py,sha256=Tosonm9A9cusImyji80G4pgdXEHNVPaCLT5TbFK_ra0,7543
60
62
  nucliadb_utils/tests/s3.py,sha256=YB8QqDaBXxyhHonEHmeBbRRDmvB7sTOaKBSi8KBGokg,2330
61
- nucliadb_utils-5.0.0.post641.dist-info/METADATA,sha256=twt2gRVvpXGQKCeR-x2zhLnb9vDehms3s9Qf0AWLxkM,2078
62
- nucliadb_utils-5.0.0.post641.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
63
- nucliadb_utils-5.0.0.post641.dist-info/top_level.txt,sha256=fE3vJtALTfgh7bcAWcNhcfXkNPp_eVVpbKK-2IYua3E,15
64
- nucliadb_utils-5.0.0.post641.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
65
- nucliadb_utils-5.0.0.post641.dist-info/RECORD,,
63
+ nucliadb_utils-5.0.0.post642.dist-info/METADATA,sha256=Pvc_Ts0moq5GdYijN-wBnOI7u5to8ZqGAdl4Vqwve1g,2078
64
+ nucliadb_utils-5.0.0.post642.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
65
+ nucliadb_utils-5.0.0.post642.dist-info/top_level.txt,sha256=fE3vJtALTfgh7bcAWcNhcfXkNPp_eVVpbKK-2IYua3E,15
66
+ nucliadb_utils-5.0.0.post642.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
67
+ nucliadb_utils-5.0.0.post642.dist-info/RECORD,,